2011-07-18 51 views
2

编写一些C++/CLI来包装现有非托管C++库后,出现了从托管类型转换为非托管类型的问题。一个简单的例子是将一个std :: string转换为一个System :: String,但是该原则适用于很多类型,即array - > vector。编写了一些转换函数后,我决定将它们打包在一个Assembly中,以便我可以重新使用它们。鉴于全球C++/CLI功能都没有本届大会外面看到我结束了这样的事情跨组件边界将托管C++/CLI类型转换为非托管类型

public ref class ClassJustToContainStaticFunctions 
{ 
public: 

    static std::string convert(System::String^ s) 
    {   
     msclr::interop::marshal_context context; 

     return(context.marshal_as<std::string>(s)); 
    } 
}; 

这符合正常,但功能转换,因为它使用的非托管类型没有得到由大会外公开可见在签名中,请参阅http://msdn.microsoft.com/en-us/library/ms235607%28v=VS.100%29.aspx了解更多信息。该解决方案通常将

#pragma make_public(std::string) 

添加到文件中,我在其他情况下没有问题地完成了这项工作。但是make_public不适用于像std :: string这样的模板类。有关信息,请参阅http://msdn.microsoft.com/en-us/library/ms235343%28v=vs.80%29.aspx

我发现了一些尝试解决工作的例子,但它们都显得很丑陋。

所以,毕竟,我的问题是我在这里失去了明显的东西?在我看来,从托管类型转换为非托管类型,特别是对于像容器类即STL.NET < - > Unmanged STL这样的东西将是一个常见问题,但经过大量搜索后,我还没有在该主题上找到太多内容。

+0

相关问题:http://stackoverflow.com/questions/4121249/best-workaround-for-compiler-error-c2158-make-public-does-not-support-native-tem仅供参考 –

+0

我已经阅读4121249的问题,这是我提到的“相当丑陋”的工作之一。无论如何感谢 – goneskiing

回答

2

由于这些函数仅在混合模式编程中需要,因此将它们包装在某些头文件/静态库中而不是程序集中。这样,您可以在每个程序中重复使用它们,但不依赖于它们的导出。

+0

+1;这些并不需要在组装中。我喜欢在头文件中使用内联函数 - 这就是Microsoft C++支持库的功能。 –

+0

我确实尝试了静态库方法,我必须承认我没有想到静态.NET程序集是可能的。无论如何,链接似乎产生一个.lib文件。然后我尝试将其添加到链接器输入并获得未解决的符号。我也尝试在.lib上使用#using,这给了我一个C1113#使用失败的错误。我无法找到关于如何链接到静态库中的C++/CLI代码的任何优秀文档。 – goneskiing

0

不是你的问题,一个特定的答案,但是,我没有像你的任何问题,这些转换功能:

 static void StringToStdString (String^s, std::string& os) 
     { 
      using namespace Runtime::InteropServices; 
      const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer(); 
      os = chars; 
      Marshal::FreeHGlobal(IntPtr((void*)chars)); 
     } 

     static const char * StringToCharPtr (String^s) 
     { 
      using namespace Runtime::InteropServices; 
      const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer(); 
      return chars; 
     } 

     static String^ StdStringToString(const std::string& _is) 
     { 
      return gcnew String(_is.c_str()); 
     } 
+0

OP的代码封装的微软C++支持库已经处理了所有这些转换。 –

+0

返回一个删除的指针? -1 –

+0

@Ben:哦,对不起,修好了那个。 –

-1

传递C++的DLL之间的标准库类是总是坏消息。如果可能的话,避免它。

+0

很久以前,这可能是真的,如果你使用混合标志,例如dubug v的优化,针对不同的DLL,但这与我在这篇文章中的问题并没有真正相关,无论如何。 – goneskiing

相关问题