gpt4 book ai didi

c# - 如何将函数指针从 C# 传递到 C++ Dll?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:18:49 25 4
gpt4 key购买 nike

C++ dll中定义的函数是:

static double (*Func1)(double);
EXTERN_C __declspec(dllexport) __stdcall double TestDelegate(double (*fun)(double))
{
Func1 = fun;
return Func1(25.0);
}


void My_Real_purpose()
{
SomeClass a;
a.SetFunction(Func1);//Define behaviour of a by C# in runtime
a.DoSomething();//Even I want it runs in another thread!
}

我试着在 C# 中这样调用它:

    class A
{
[DllImport("DllName.dll")]
public extern static double TestDelegate(IntPtr f);

public delegate double MyFuncDelegate(double x);

public static double MyFunc(double x)
{
return Math.Sqrt(x);
}

static MyFuncDelegate ff;
static GCHandle gch;
public static double Invoke()
{
ff = new MyFuncDelegate(MyFunc);
gch = GCHandle.Alloc(ff);
double c = TestDelegate(Marshal.GetFunctionPointerForDelegate(ff));//Error occurs this line
gch.Free();
return c;
}

}

编译没有报错,但是运行时VS2012报“Access Violation Exception”错误。

我搜索并尝试了很多方法,比如传递一个委托(delegate)而不是一个IntPtr,但都失败了。

那么,在包含函数指针的dll中如何正确使用API​​函数?或者如何实现“My_Real_purpose”函数?

最佳答案

您的委托(delegate)使用 cdecl 调用约定。因此,在 C# 中,您可以这样声明委托(delegate):

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double CallbackDelegate(double x);

作为替代方案,您可以决定将 C++ 中的函数指针声明为 __stdcall,在这种情况下,您将删除 UnmanagedFunctionPointer 属性并依赖默认调用约定正在 CallingConvention.StdCall

这样实现:

public static double MyFunc(double x)
{
return Math.Sqrt(x);
}

为了使非托管函数指针保持事件状态(防止 GC),您需要在变量中保存委托(delegate)的实例。

private static CallbackDelegate delegateInstance;
....
delegateInstance = MyFunc;

在此处的简单示例中,C++ 代码不在 TestDelegate 之外使用非托管函数指针,但在更复杂的示例中,您可能会这样做,在这种情况下,您必须保持非托管函数指针处于事件状态。

您导入的函数声明如下:

[DllImport("DllName.dll")]
public extern static double TestDelegate(CallbackDelegate f);

然后你可以这样调用它:

double retval = TestDelegate(delegateInstance);

关于c# - 如何将函数指针从 C# 传递到 C++ Dll?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43226928/

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