开发者

Converting managed C++/CLI types to unmanaged types across assembly boundaries

开发者 https://www.devze.com 2023-03-20 20:38 出处:网络
Having been writing some C++/CLI to wrap an existing unmanaged C++ library the issue of converting from managed types to unmanaged types came up. A simple example off this is converting a std::string

Having been writing some C++/CLI to wrap an existing unmanaged C++ library the issue of converting from managed types to unmanaged types came up. A simple example off this is converting a std::string to a System::String but the principle applies to many types i.e. array -> vector. Having written some conversion function I decided to package them up in an Assembly so I can re-use them. Given that global C++/CLI functions are not visible outside the current Assembly I ended up with things like this

public ref class ClassJustToContainStaticFunctions
{
public:

    static std::string convert( System::String^ s )
    {           
        msclr::intero开发者_StackOverflow中文版p::marshal_context context;

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

This complies fine but the function convert does not get made publicly visible outside the Assembly because it uses an unmanaged type in the signature, see here http://msdn.microsoft.com/en-us/library/ms235607%28v=VS.100%29.aspx for more on this. The solution is normally to add

#pragma make_public(std::string)

to the file and I have done this in other situations without problems. However make_public does not work for templated classes like std::string. See here http://msdn.microsoft.com/en-us/library/ms235343%28v=vs.80%29.aspx for some info.

I found a few attempts at work arounds for instance but they all seemed pretty ugly.

So, after all that, my question is am I missing something obvious here? It seems to me that converting from managed to unmanaged types, particularly for things like container classes i.e. STL.NET <--> Unmanged STL would be a common issue but after much searching I haven't found much on the topic.


As these functions are only needed in mixed mode programming, wrap them up in some header files / static library instead of an assembly. This way you can re-use them in every program but you are not dependent on them being exported.


Not a particular answer for your question but, I do not have any problems like yours, with those conversion functions :

        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());
        }


Passing C++ standard library classes between DLLs is always bad news. Avoid it if you possibly can.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号