将std :: string从VC ++ 2005传递到VC ++ 6 DLL导致垃圾

时间:2009-11-26 15:34:24

标签: visual-c++

我有一个用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;  
}  

3 个答案:

答案 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的更好选择。