我正在尝试将一些静态C++库迁移到带有C接口的DLL中,因此不需要为我们希望支持的每个版本的Visual (即CRT)构建一个单独的库版本。但是,我确实喜欢在一些函数调用中使用STL对象的方便。我想出了一些似乎可行的东西,但我想知道是否有一些隐藏的东西,我只是没有想到。
下面是我想出的方法来获得函数的STL版本,同时仍然保持Visual独立性。
原始图书馆功能:
//library.h
...
std::wstring GetSomeString();
...
StringGenerator* mStrGen; //assume forward declared for pimpl implementation
//library.cpp
std::wstring library::GetSomeString()
{
return mStrGen->GetString(); //returns a wstring;
}首先,我创建了一个提供C接口的私有函数
//library.h
__declspec(dllexport) void GetSomeStringInternal(wchar_t* pSomeString);
//library.cpp
void library::GetSomeString(wchar_t*& pSomeString)
{
if(pSomeString!= nullptr) {
delete [] pSomeString; //assumes allocated by the DLL
}
std::wstring tmpString(mStrGen->GetString());
size_t stringLength(tmpString.size());
stringToReturn = new wchar_t[stringLength + 1];
wcscpy_s(pSomeString, stringLength + 1, tmpString.c_str());
}接下来,我添加了一个私有函数,用于释放DLL分配的内存。
//library.h
__declspec(dllexport) void FreeArray(void* arrayPtr);
//library.cpp
void library::FreeArray(void* arrayPtr)
{
if(arrayPtr) {
delete [] arrayPtr;
}
}最后,我将返回字符串的原始C++函数转换为调用内部C接口函数的函数
//library.h
std::wstring GetSomeString()
{
std::wstring someString(L"");
wchar_t* pSomeString= NULL;
GetSomeStringInternal(pSomeString);
someString = pSomeString;
FreeArray(pSomeString);
return someString;
}
//library.cpp
//removed GetSomeString from cpp since it is defined in header我的想法是,由于头将在每次包含时进行编译,所以使用不同版本的CRT的应用程序将使用CRT的实现来编译该函数。传入和输出库的所有数据都使用C接口来保持兼容性,库分配和释放内存,这样您就不会遇到试图从不同版本中释放内存的CRT的一个版本。
它似乎如我所愿:
我是否遗漏了什么,或者这是否是一种向与Visual版本无关的库提供C++接口的有效方法?
附带注意:如果我有一个使用std::shared_ptr<library>的程序,但是还没有对这个问题进行足够的研究,我就会遇到一些删除问题,并且可能会有一个关于这个问题的后续问题。
发布于 2012-09-18 21:42:26
有一件事我可以看到成为一个问题,如果您实际上需要通过引用传递大对象的性能原因。通过将所有数据复制到兼容格式和从兼容格式复制来处理二进制兼容性问题,这很好,直到成为性能问题。
https://stackoverflow.com/questions/12483209
复制相似问题