Last active
December 15, 2015 11:38
-
-
Save martinmoene/5254009 to your computer and use it in GitHub Desktop.
A String class to use over a DLL boundary, enabling the use of different compiler versions at both ends.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Note: use _bstr_t. It's part of COM and present in VC6 and newer versions of Visual C++. | |
// It's an encapsulation of the BSTR string type that has a shared *C* API. It's used for | |
// interlanguage operability, so going between compiler/library versions is *not* a problem. | |
// | |
// Thanks to the kind people on the accu-general mailing list of http://accu.org/ | |
// | |
//============================================================================ | |
// String.h | |
#ifndef G_STRING_H_INCLUDED | |
#define G_STRING_H_INCLUDED | |
// define DLL_EXPORTING when generating DLL | |
#ifdef DLL_EXPORTING | |
# define DLL_PUBLIC __declspec( dllexport ) | |
#else | |
# define DLL_PUBLIC __declspec( dllimport ) | |
#endif | |
#include <string> | |
class DLL_PUBLIC String | |
{ | |
public: | |
~String(); | |
explicit String( char const * const text ); | |
String( String const & other ); | |
String & operator=( String rhs ); | |
String & operator=( char const * const text ); | |
String & swap( String & other ); | |
operator char const *() const | |
{ | |
return c_str(); | |
} | |
char const * c_str() const | |
{ | |
return get(); | |
} | |
friend String to_String( std::string const & text ) | |
{ | |
return String( text.c_str() ); | |
} | |
friend std::string to_string( String const & text ) | |
{ | |
return text.c_str(); | |
} | |
friend char const * to_cstr( String const & text ) | |
{ | |
return text.c_str(); | |
} | |
private: | |
const char * get() const; | |
private: | |
class Impl; | |
Impl const * impl; | |
}; | |
#endif // G_STRING_H_INCLUDED | |
//============================================================================ | |
// String.cpp | |
#include "String.h" | |
class DLL_PUBLIC String::Impl | |
{ | |
public: | |
~Impl() | |
{ | |
delete text; | |
} | |
Impl( char const * const text ) | |
: text ( _strdup( text ) ) | |
{ | |
} | |
Impl * clone() const | |
{ | |
return new Impl( text ); | |
} | |
char const * const text; | |
}; | |
DLL_PUBLIC String::~String() | |
{ | |
delete impl; | |
} | |
DLL_PUBLIC String::String( char const * const text ) | |
: impl( new Impl( text ) ) | |
{ | |
} | |
DLL_PUBLIC String::String( String const & other ) | |
: impl( other.impl->clone() ) | |
{ | |
} | |
DLL_PUBLIC String & String::swap( String & other ) | |
{ | |
std::swap( impl, other.impl ); | |
return *this; | |
} | |
DLL_PUBLIC String & String::operator=( String rhs ) | |
{ | |
rhs.swap( *this ); | |
return *this; | |
} | |
String & String::operator=( char const * const text ) | |
{ | |
return *this = String( text ); | |
} | |
DLL_PUBLIC const char * String::get() const | |
{ | |
return impl->text; | |
} | |
//============================================================================ | |
// String-test.cpp | |
// VC2010: cl -nologo -W3 -EHsc -LD -MD -D_CRT_SECURE_NO_WARNINGS -DDLL_EXPORTING String.cpp | |
// VC6: cl -nologo -W3 -EHsc String-test.cpp String.lib | |
#include "String.h" | |
#include <iostream> | |
std::ostream & operator<<( std::ostream & os, String const & text ) | |
{ | |
return os << text.c_str() ; | |
} | |
int main() | |
{ | |
String text1( "Hello world"); | |
std::cout << text1 << std::endl; | |
std::cout << ((char const *)text1) << std::endl; | |
std::cout << to_cstr( text1 ) << std::endl; | |
String text2( text1 ); | |
std::cout << text2 << std::endl; | |
String text3( String( "Hi there" ) ); | |
std::cout << text3 << std::endl; | |
String text4( text2 ); | |
text4 = text3; | |
std::cout << text4 << std::endl; | |
text4 = "Ho Ho"; | |
std::cout << text4 << std::endl; | |
text4 = to_String( std::string( "Hi Hi" ) ); | |
std::cout << text4 << std::endl; | |
std::string stdtext1( text1 ); | |
std::cout << stdtext1 << std::endl; | |
std::string stdtext2( to_string( text1 ) ); | |
std::cout << stdtext2 << std::endl; | |
return 0; | |
} | |
//============================================================================ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment