gpt4 book ai didi

C# GetFunctionPointerForDelegate cdecl 而不是 stdcall

转载 作者:可可西里 更新时间:2023-11-01 18:32:39 28 4
gpt4 key购买 nike

我正在尝试使用具有回调机制的 (C) 第三方库,该机制缺少任何可能的识别调用上下文的方法。我的主要项目在 C# 中,我的包装器是一个调用 C 库 API 的 C++/CLI 项目。

为了解决这个问题,我尝试使用 Marshal::GetFUnctionPointerForDelegate。这是我的 C# 代码:

void Init(Handler Callback)
{
// Create a wrapper lambda in case Callback is a non-static method.
instance.CreateBuffers((x, y) => Callback(x, y));
}

然后,在 C++/CLI 代码中:

void CreateBuffers(Handler^ Callback)
{
pinCallback = GCHandle::Alloc(Callback);

void (*callback)(int, int) = (void (__stdcall *)(int, int))Marshal::GetFunctionPointerForDelegate(Callback).ToPointer(),
// Use 'callback' in third party library...
}

所有这一切的问题在于,根据 http://msdn.microsoft.com/en-us/library/367eeye0.aspx ,来自 Marshal::GetFunctionPointerForDelegate 的函数指针是一个 stdcall 函数,但我的 C 回调函数是 cdecl。我怎样才能在这里获得 cdecl 兼容功能?

最佳答案

我认为实现此目的的最简单方法是将委托(delegate)类型声明为 C#,并使用 UnmanagedFunctionPointer 属性指定调用约定。

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate ...

然后让您的 C++/CLI 代码接收一个普通的 native C++ 函数指针。您可以传递委托(delegate)的实例,因为委托(delegate)具有该属性,所以编码器知道要做什么。

这允许您跳过 GetFunctionPointerForDelegate 步骤。事实上,它可以让您直接跳过 C++/CLI 层,但我希望您不想那样做。

只要非托管代码可以看到函数指针,请确保您的托管代码保留对委托(delegate)的引用。如果您不这样做,那么垃圾收集器可能会把地毯从您下面拉下来,因为它看不到非托管代码持有的引用。

当然,这个主题之前已经在此处介绍过。 Hans Passant 在这里有一个详细的答案,值得一读:Correct way to call a C DLL method from C#

关于C# GetFunctionPointerForDelegate cdecl 而不是 stdcall,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19740140/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com