2

一直在编写一些 C++/CLI 来包装现有的非托管 C++ 库,从托管类型转换为非托管类型的问题出现了。一个简单的例子是将 std::string 转换为 System::String 但该原理适用于许多类型,即数组 -> 向量。编写了一些转换函数后,我决定将它们打包在一个程序集中,以便我可以重用它们。鉴于全局 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 将是一个常见问题,但经过大量搜索后,我没有找到太多关于该主题的内容。

4

3 回答 3

2

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

于 2011-07-18T12:44:28.333 回答
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());
        }
于 2011-07-18T12:52:45.787 回答
-1

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

于 2011-07-18T19:52:13.627 回答