我有一个用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;
}
答案 0 :(得分:3)
诸如std :: string之类的类不一定在每个版本的运行时库中以相同的方式定义(即使它们具有相同的名称),因此不应该以这种方式混合库。另一方面,int和char *等类型对于给定的平台是相同的,因此您可以传递它们。
在您的示例中,最好将字符串作为(指针,大小)对传递,或者简单地作为以空字符结尾的字符串传递。
编辑:忘了提及使用相同编译器版本的明显解决方案。如果要传递对象,请执行此操作。
答案 1 :(得分:0)
不要这样做。它不起作用。
C ++没有定义固定的ABI,因此通常不能在不同编译器编译的库或翻译单元之间传递非POD类型。
在您的情况下,VC6和VC8具有不同的std::string
定义(并且编译器也可能插入不同的填充和其他更改),结果是垃圾,和/或不可预测的行为和崩溃。
如果你需要将数据传递给VC6 DLL(一个更好的选择可能是在一个理智的编译器下重新编译该代码),你必须坚持你可以确定它会工作的类型。这意味着1)POD类型(内置基元,如char*
,或仅包含POD类型的C结构)或COM对象。
答案 2 :(得分:0)
您可以使用C接口编写包装器DLL。如果单独的p调用无法处理互操作,则可能需要C ++ / CLI包装器。在ATL中编写COM服务器可能是在本机代码中提供面向对象的接口并避免在C ++ / CLI中编写另一个包装器DLL的更好选择。