我的问题与导出带有 STL 的 C++ 类有关。例如:
class __declspec(dllexport) Hello
{
std::string name;
public:
std::string& getName();
void setName(const std::string& name);
}
各种文章似乎都表明这是非常糟糕的,这是可以理解的。一切都必须使用相同的编译器设置和 CRT 版本进行编译。否则一切都会崩溃和燃烧。
问题:
我不明白为什么只有数据成员似乎有问题。使用下面的代码,我得到:“ C4251:需要有 dll 接口才能被类的客户端使用”;这显然是通过导出实例化的 std::string 来解决的:
struct __declspec(dllexport) SomeClass
{
// Removes the warning?
// http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
// template class __declspec(dllexport) std::string;
std::string name; // Compiler balks at this
}
固定版本是:
// Export the instantiations of allocator and basic_string
template class __declspec(dllexport) std::allocator<char>;
template class __declspec(dllexport) std::basic_string<char, std::char_traits<char>, std::allocator<char> >;
struct __declspec(dllexport) SomeClass
{
std::string name; // No more balking!
}
(当您尝试使用 DLL 时,这将给 LNK2005“basic_string 已定义”,这意味着您不必在客户端上的 CRT 中链接 - 所以它最终使用 DLL 中的实例化)。
返回类型和参数在 STL 中似乎没有问题,并且不接受从编译器获得的数据成员的相同处理。
// No exporting required?
struct __declspec(dllexport) SomeOtherClass
{
std::string doSomething1(); // No problemo
void doSomething2(const std::string& s); // No problemo
}
附加信息(上面有问题)
同时:
class A {
std::string foo() { return std::string(); }
// std::string& foo(); gives the same result!
// std::string* foo(); also gives the same result!
}
class B {
std::string a;
}
似乎都没有导出 std::basic_string 或 std::allocator。相反,它们只导出类的成员/函数。
但是,问题中提到的固定版本同时导出了 basic_string 和分配器。