How can I marshall a vector from a C++ dll to a C# application?

前端 未结 3 988
名媛妹妹
名媛妹妹 2020-12-10 06:26

I have a C++ function that produces a list of rectangles that are interesting. I want to be able to get that list out of the C++ library and back into the C# application th

3条回答
  •  眼角桃花
    2020-12-10 07:10

    Yes. You can. Actually, not just std::vector, std::string, std::wstring, any standard C++ class or your own classes can be marshaled or instantiated and called from C#/.NET.

    Wrapping a std::vector in C# is indeed possible with just regular P/Invoke Interop, it is complicated though. even a std::map of any type can be done in C#/.NET.

    public class SampleClass : IDisposable
    {    
        [DllImport("YourDll.dll", EntryPoint="ConstructorOfYourClass", CharSet=CharSet.Ansi,          CallingConvention=CallingConvention.ThisCall)]
        public extern static void SampleClassConstructor(IntPtr thisObject);
    
        [DllImport("YourDll.dll", EntryPoint="DestructorOfYourClass", CharSet=CharSet.Ansi,          CallingConvention=CallingConvention.ThisCall)]
        public extern static void SampleClassDestructor(IntPtr thisObject);
    
        [DllImport("YourDll.dll", EntryPoint="DoSomething", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
        public extern static void DoSomething(IntPtr thisObject);
    
        [DllImport("YourDll.dll", EntryPoint="DoSomethingElse", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
        public extern static void DoSomething(IntPtr thisObject, int x);
    
        IntPtr ptr;
    
        public SampleClass(int sizeOfYourCppClass)
        {
            this.ptr = Marshal.AllocHGlobal(sizeOfYourCppClass);
            SampleClassConstructor(this.ptr);  
        }
    
        public void DoSomething()
        {
            DoSomething(this.ptr);
        }
    
        public void DoSomethingElse(int x)
        {
            DoSomethingElse(this.ptr, x);
        }
    
        public void Dispose()
        {
            if (this.ptr != IntPtr.Zero)
            {
                // The following 2 calls equals to "delete object" in C++
                // Calling the destructor of the C++ class will free the memory allocated by the native c++ class.
                SampleClassDestructor(this.ptr);
    
                // Free the memory allocated from .NET.
                Marshal.FreeHGlobal(this.ptr);
    
                this.ptr = IntPtr.Zero;
            }
        }
    }
    

    Please see the below link,

    C#/.NET PInvoke Interop SDK

    (I am the author of the SDK tool)

    Once you have the C# wrapper class for your C++ class ready, it is easy to implement ICustomMarshaler so that you can marshal the C++ object from .NET.

    http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustommarshaler.aspx

提交回复
热议问题