【问题标题】:how to use cdecl callback with pinvoke如何在 pinvoke 中使用 cdecl 回调
【发布时间】:2011-06-23 19:00:03
【问题描述】:

我有一个具有 cdecl 回调的 c 库。如何在 c# 中使用这些。

一切似乎都说它们一定是stdcall回调

要清楚:

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

其中 del 必须以 cdecl 方式调用

【问题讨论】:

  • 您是在尝试在 C# 中创建一个 Cdecl 回调(即非托管代码可以调用的 Cdecl 函数),还是在尝试调用非托管(即本机 C)Cdecl来自 C# 的函数?

标签: c# callback pinvoke


【解决方案1】:

看看这个。该功能自 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);

【讨论】:

    【解决方案2】:
    1. 使用 .NET 2.0 编译,使用 2005 编译器!!
    2. 反转参数方向。

    由于 2005 编译器添加了一些保护代码,它可以工作。

    编辑:如果您可以在本机代码中制作 shim,请不要尝试此操作。

    【讨论】:

    • cdecl 不仅仅是参数顺序。 StdCall 期望被调用函数清理堆栈,而Cdecl 期望调用者清理堆栈。混合调用约定会导致堆栈不平衡。
    • @Jim:我知道。我偶然发现 2005 编译器在编组时包含修复逻辑。当我升级到 2010 编译器时,它不起作用,我花了很长时间才弄清楚原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 2012-03-17
    • 2023-03-21
    • 2011-09-25
    • 2011-07-04
    • 2011-03-25
    • 2023-03-28
    相关资源
    最近更新 更多