2014-11-21 180 views
-1

問題是我有一個C++ DLL,我想在我的C#項目中使用。在C中調用C++ DLL

有問題的函數原型:

int MRK3LINK_Open(void (*pfLog)(const char* s),void (*pfErrorOut)(const char* s));  

的文檔指出:

  • 的pflog是一個記錄類型爲const char的處理函數*指針。
  • pfErrorOut是指向const char *類型的錯誤輸出處理函數的指針。

以及如何從C++調用的DLL函數的例子:

static void _LogHandler(const char* sLog) { 
    printf(sLog); 
} 

static void _ErrorOutHandler(const char* sError) { 
    MessageBox(NULL, sError, "2-Link", MB_OK); 
} 

MRK3LINK_Open(_LogHandler, _ErrorOutHandler); 

我現在被困在這2天。你能提供一些提示嗎?

謝謝。

+0

兩個可能的錯誤,你沒有發佈足夠的。您可能忘記了委託聲明中的[UnmanagedFunctionPointer]屬性,以確保CLR知道這是一個CallingConvention.Cdecl函數指針。而且你並沒有將委託對象存儲在任何地方,所以他們會收集垃圾,當C代碼進行回調時會崩潰程序。 – 2014-11-21 12:15:30

+0

感謝您的建議,您是對的。 – 2014-12-16 13:28:59

回答

1

這兩個參數是函數指針。他們將用C++映射到代表。就像這樣:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
public delegate void LogHandlerDelegate(string str); 

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
public delegate void ErrorOutHandlerDelegate(string error); 

然後你導入功能:

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)] 
public static extern int MRK3LINK_Open(
    LogHandlerDelegate LogHandler, 
    ErrorOutHandlerDelegate ErrorOutHandler 
); 

那麼你通常的方式創建的代表,並通過他們向MRK3LINK_Open。如果非託管代碼引用它們並在MRK3LINK_Open返回後調用它們,請確保您存儲對委託的引用。否則垃圾收集器有責任收集它們。

+0

感謝您的回答,我現在擁有了:) – 2014-12-16 13:29:37