How to pass function pointer from C# to a C++ Dll?(如何将函数指针从 C# 传递给 C++ Dll?)
问题描述
C++ dll中定义的函数是:
The function defined in C++ dll is:
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# 中这样调用它:
And I tried to call it in C# like this:
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"的错误.
It is compiled without error.But when it runs,VS2012 display an error of "Access Violation Exception".
我已经搜索并尝试了很多方法,例如传递委托而不是 IntPtr,但所有方法都失败了.
I have searched and tried a lot of ways,such as passing a delegate rather than a IntPtr,but all of them turned out to be failed.
那么,在包含函数指针的dll中使用API函数的正确方法是什么?或者如何实现My_Real_purpose"函数?
So,what is the correct way to use an API function in a dll which contains function pointer?Or how to realize "My_Real_purpose" function?
推荐答案
您的委托使用 cdecl 调用约定.因此,在 C# 中,您可以像这样声明委托:
Your delegate uses the cdecl calling convention. In C# you would therefore declare the delegate like this:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double CallbackDelegate(double x);
作为替代方案,您可以决定将 C++ 中的函数指针声明为 __stdcall,在这种情况下,您将删除 UnmanagedFunctionPointer 属性并依赖默认调用约定是 CallingConvention.StdCall.
As an alternative, you could decide to declare the function pointer in C++ as __stdcall, in which case you would remove the UnmanagedFunctionPointer attribute and rely on the default calling convention being CallingConvention.StdCall.
这样实现:
public static double MyFunc(double x)
{
return Math.Sqrt(x);
}
为了使非托管函数指针保持活动状态(防止 GC),您需要在变量中保存委托的实例.
In order to keep the unmanaged function pointer alive (guarding against GC), you need to hold an instance of the delegate in a variable.
private static CallbackDelegate delegateInstance;
....
delegateInstance = MyFunc;
在您在这里的简单示例中,C++ 代码不使用 TestDelegate 之外的非托管函数指针,但在更复杂的示例中,您可以这样做,在这种情况下,您必须保留非托管函数指针活着.
In the simple example that you have here, the C++ code does not use the unmanaged function pointer outside of TestDelegate, but in a more complex example you may do so, in which case you must keep the unmanaged function pointer alive.
你导入的函数是这样声明的:
The function that you import is declared like this:
[DllImport("DllName.dll")]
public extern static double TestDelegate(CallbackDelegate f);
你可以这样称呼它:
double retval = TestDelegate(delegateInstance);
这篇关于如何将函数指针从 C# 传递给 C++ Dll?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何将函数指针从 C# 传递给 C++ Dll?
基础教程推荐
- 从 C# 控制相机设备 2022-01-01
- 在 VB6 或经典 ASP 中使用 .NET 2022-01-01
- 重新排序 WPF TabControl 中的选项卡 2022-01-01
- SonarQube C# 分析失败“不是指针的有效行偏移" 2022-01-01
- 如果条件可以为空 2022-01-01
- 更新 Visual Studio 中的 DataSet 结构以匹配新的 SQL 数据库结构 2022-01-01
- C# 9 新特性——record的相关总结 2023-04-03
- Mono https webrequest 失败并显示“身份验证或解密失败" 2022-01-01
- 将数据集转换为列表 2022-01-01
- 获取C#保存对话框的文件路径 2022-01-01
