2012-06-29 26 views
0

我有一個C++ DLL,其中導出了以下函數。傳遞wstring,字符串和從C#到C++的enum變量的引用(非託管DLL)

double getDouble(std::wstring filename, std::string ID, status &stCode); 

int getInt(std::wstring filename, std::string ID, status &stCode); 

float getFloat(std::wstring filename, std::string ID, status &stCode); 

string getString(std::wstring filename, std::string ID, status &stCode); 

int* getIntArray(std::wstring filename, std::string ID, status &stCode); 

float* getFloatArray(std::wstring filename, std::string ID, status &stCode); 

string* getStringArray(std::wstring filename, std::string ID, status &stCode); 

其中狀態是枚舉類型的...

現在,我想在我的C#.NET應用程序使用此DLL ......誰能告訴我怎麼做我delclare在C#中推崇的方法和可以撥打此方法....在此先感謝...

+0

可能重複http://stackoverflow.com/questions/158628/marshal-c-string-class-in-c-sharp -p-invoke) - 簡短的回答你需要改變你的方法來獲取字符緩衝區。 – shf301

回答

0
[DllImport("external.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] 
    public static extern MbStatus queue_accept(
     int reader, 
     [MarshalAs(UnmanagedType.LPStr)] string status); 

查找DllImport屬性的參數。根據您的DLL,這些可能需要調整!

備註:我通常將外部dll包裝在一個接口和一個代碼層中以將其解耦以進行測試並使用依賴注入進行加載。我也不會改變命名約定。

public interface IExternalDllInterop 
{ 
    MB_STATUS queue_accept(int reader, string status); 
} 

public class AmbInterop : IAmbInterop 
{ 
    public MbStatus queue_accept(int reader, string status) 
    { 
     return StaticAmbInterop.mb_queue_accept(reader, message, status); 
    } 
} 
+0

謝謝你的傢伙......我嘗試了第一種方法,但它不適合我。 – Kundan

0

是的。您可以。實際上,並非std::stringstd::wstring,任何標準C++類或您自己的類都可以編組或從C#/ .NET中調用實例化和調用。您需要爲每個C++類編寫一個包裝類,然後才能在.NET中編組它們。

從.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/library/system.runtime.interopservices.icustommarshaler.aspx

[元帥C++在C#P /調用 「字符串」 類(的
相關問題