2012-01-28 39 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