2012-01-28 78 views
1

在一个C++侧I具有以下类声明:编组C++类作为结构

class MyClass { 
    ...fields 
    MyClass(); 
    ~MyClass(); }; 

该类在内部DLL一些方法中。它传递给他们并从他们回来。 如何用C#表示它?我需要使它与C++ dll完全兼容。

该类没有方法只有无参数的构造函数和析构函数被定义。任何想法如何编组?不幸的是,我不能使用C++ \ CLI,但我希望可以用C#来完成。

我只有一个想法,就是在C#端将其表示为结构(不幸的是,我无法访问C++代码)并尝试Marshal.PtrToStructure。但我不确定它会起作用。

有什么建议吗?谢谢。

+0

所以类只用于其领域?它的身份并不重要?析构函数是做什么的? – svick 2012-01-28 13:34:46

+0

可以马歇尔与Marshal.PtrToStructure,定义类与性质和构造器,析构函数: '[StructLayout(LayoutKind.Sequential)] 公共MyClass类 { ...字段 MyClass的(); 〜MyClass(); }' – pistipanko 2012-01-28 13:55:22

+0

@pistipanko,非常感谢!我会尝试。 – mrt 2012-01-28 14:08:24

回答

1

这在C#中是不可能的。它可以在托管和本地之间映射数据片段,但不会影响行为。一个C++类固有地提供行为,因此不能直接编组。

你可以做的事情是编组IntPtr到本地对象,并创建一个瘦PInvoke层,只使用IntPtr来访问该类型的数据段。例如让我说我有以下的C++类。

class MyClass { 
public: 
    int Field; 
}; 

我可以暴露它的行为与下面的一组C函数。

extern "C" { 

    void* MyClass_Create() { 
    return new MyClass(); 
    } 

    void MyClass_Delete(void* pValue) { 
    delete reinterpret_cast<MyClass*>(pValue); 
    } 

    int MyClass_GetField(void* pValue) { 
    return reinterpret_cast<MyClass*>(pValue)->Field; 
    } 

    void MyClass_SetField(void* pValue, int field) { 
    reinterpret_cast<MyClass*>(pValue)->Field = field; 
    } 
} 

现在,我已经曝光了这款通过C函数我可以创建在它的上面薄薄的托管包装

internal static class NativeMethods { 
    [DllImport("example.dll")] 
    internal static extern IntPtr MyClass_Create(); 

    [DllImport("example.dll")] 
    internal static extern void MyClass_Destroy(IntPtr ptr); 

    [DllImport("example.dll")] 
    internal static extern int MyClass_GetField(IntPtr prt); 

    [DllImport("example.dll")] 
    internal static extern void MyClass_SetField(IntPtr ptr, int field); 
} 


public class MyClass : IDisposable { 
    private readonly IntPtr m_pointer; 

    public int Field { 
    get { return NativeMethods.MyClass_GetField(m_pointer); } 
    set { NativeMethods.MyClass_SetField(m_pointer, value); } 
    } 

    public MyClass() { 
    m_pointer = NativeMethods.MyClass_Create(); 
    } 

    // Create from existing 
    public MyClass(IntPtr pointer) { 
    m_pointer = pointer; 
    } 

    public void Dispose() { 
    NativeMethods.MyClass_Destroy(m_pointer); 
    } 
} 
+0

C++ DLL的所有非纯虚和非模板方法都被导出,因为它们必须从C++本机代码中使用,因此,您肯定可以使用调用此调用约定从C#调用它们。你不一定用c风格的方法来包装它们。 – xInterop 2013-04-28 17:48:22