2011-02-08 45 views
8

我有一個c庫有cdecl回調。我怎樣才能使用這些從C#。如何使用cdecl回調與pinvoke

一切似乎是說,他們必須STDCALL回調

是明確的:

delegate int del(); 
[dllimport("mylib.dll",CallingConvention=CallingConvention.Cdecl)] 
public static extern int funcwithcallback(del foo); 

德爾地方必須調用CDECL明智與.NET 2.0,使用

+0

你想創建在C#`Cdecl`回調(即`Cdecl`函數,非託管代碼可以調用),或者是你試圖從C#調用非託管(即本機C)`Cdecl`函數? – 2011-02-09 00:03:54

回答

14

看看這個。這個功能從1.1開始就已經出現了,所以它應該涵蓋你正在使用的任何.NET版本。你只需要指定CallingConvention。

CallingConvention Documenation at MSDN

您還可以看看這篇文章的代碼項目:

Using the _CDECL calling convention in C#

編輯:另外,這裏是FreeImage.NET一個例子。

static FreeImage_OutputMessageFunction freeimage_outputmessage_proc = NULL; 
DLL_API void DLL_CALLCONV 
FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf); 

然後在C#的一面,簡單地說:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
public delegate void FreeImage_OutputMessageFunction(FREE_IMAGE_FORMAT 
format, string msg); 

[DllImport(dllName, EntryPoint="FreeImage_SetOutputMessage")] 
public static extern void SetOutputMessage(FreeImage_OutputMessageFunction 
omf); 
-1
  1. 編譯2005編譯器!
  2. 顛倒參數方向。

它的工作原因是2005編譯器添加了一些保護代碼。

編輯:不要嘗試這個,如果你可以在本機代碼中做一個墊片。

+1

'cdecl`不僅僅是參數順序。 `StdCall`期望被調用的函數清理堆棧,而`Cdecl`期望調用者清理堆棧。混合調用約定會導致堆棧不平衡。 – 2011-02-09 00:00:24

+0

@Jim:我知道。我偶然發現,2005編譯器在編組時包含修正邏輯。當我升級到2010年的編譯器時,它不起作用,我花了一段時間找出原因。 – Joshua 2011-02-09 03:11:05