我有一个用VC++6编写的动态链接库,我用VC++2005编写了一些代码,它调用了本机VC++6库。每当我将std::string传递给本机库时,结果总是垃圾。然而,如果我传递其他类型,如char *、int等,则不会发生这种情况。任何理想的原因是什么?
下面的代码说明了这一点。
// VC++ 6代码
class __declspec(dllexport) VC6
{
public:
VC6();
void DoSomething(const std::string &s);
}
VC6()::VC6() {}
void VC6::DoSomething(const std::string &s)
{
std::cout << s; // Resulting output on screen is garbage
} // VC++ 2005代码
void VC2005::DoSomething()
{
VC6 *vc6 = new VC6();
std::string s("Test String");
vc6->DoSomething(s);
delete vc6;
} 发布于 2009-11-26 15:51:21
不要这样做。它不起作用。
C++不定义固定的ABI,因此通常不能在不同编译器编译的库或翻译单元之间传递非POD类型。
在您的示例中,VC6和VC8对std::string有不同的定义(编译器还可以插入不同的填充和其他更改),结果是垃圾和/或不可预测的行为和崩溃。
如果您需要将数据传递给一个VC6 DLL (更好的选择可能是在一个正常的编译器下重新编译该代码),您必须坚持您可以确保它能够工作的类型。这意味着1) POD类型(或者内置原语,比如char*,或者C结构只包含POD类型),或者COM对象。
发布于 2009-11-26 15:43:53
像std::string这样的类并不一定在运行时库的每个版本中都以相同的方式定义(即使它们的名称相同),所以不应该以这种方式混合库。另一方面,对于给定的平台,int和char*等类型是相同的,因此您可以传递它们。
在您的示例中,最好将字符串作为(指针,大小)对传递,或者简单地作为以空结尾的字符串传递。
编辑:忘了提到使用相同编译器版本的明显解决方案。如果您想要传递对象,请执行此操作。
发布于 2009-11-29 00:31:31
可以用C接口编写包装器DLL。如果单凭p调用无法处理互操作,则可能需要一个C++/CLI包装器。用ATL编写COM服务器可能是在本机代码中提供面向对象接口和避免在C++/CLI中编写另一个包装器DLL的更好选择)。
https://stackoverflow.com/questions/1804359
复制相似问题