我在本机DLL中有一个函数,定义如下:

#include <string>
void SetPath(string path);

我试图把它放在微软的P / Invoke Interop助手中,但它在“字符串”上窒息了。 class(我认为是来自MFC?)。

我尝试将它编组为各种不同的类型(C#String,char [],byte []),但每次我得到NotSupportedException或Native Assembly Exception(取决于我尝试过的编组)。

有没有人使用本机字符串类的Native / Managed Interop?有没有办法让这个元帅?我是否必须自己编写Marshaler?

有帮助吗?

解决方案

看起来您正在尝试使用C ++标准库字符串类。我怀疑元帅会很容易。最好坚持使用char *和Marshal作为StringBuilder。这就是我通常做的事情。您必须添加一个为您生成C ++字符串的包装器。

其他提示

PInvoke互操作助手仅支持C而不是C ++。不幸的是,MFC String类(CString我相信?)是C ++,不会通过助手工作。而是尝试使用以下

void SetPath(__in const WCHAR* path);

是。您可以。实际上,不仅仅是 std :: string std :: wstring ,任何标准C ++类或您自己的类都可以被编组或实例化并从C#/ .NET调用。 / p>

从.NET世界实例化C ++对象的基本思想是从.NET分配C ++对象的确切大小,然后调用从C ++ DLL导出的构造函数来初始化对象,然后您就可以调用任何函数来访问该C ++对象,如果任何方法涉及其他C ++类,您也需要将它们包装在C#类中,对于具有基本类型的方法,您可以简单地P / Invoke它们。如果你只有几种方法可以调用,那很简单,手动编码不会花费很长时间。完成C ++对象后,可以调用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="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()
    {
        Marshal.FreeHGlobal(this.ptr);
    }
}

有关详细信息,请参阅以下链接

C#/。 NET PInvoke Interop SDK

(我是SDK工具的作者)

准备好C ++类的C#包装类后,可以很容易地实现 ICustomMarshaler ,这样就可以从.NET编组C ++对象。

http://msdn.microsoft.com/ EN-US /库/ system.runtime.interopservices.icustommarshaler.aspx

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top