首页 / C# / 在C#中传递函数指针
在C#中传递函数指针
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了在C#中传递函数指针,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3032字,纯文字阅读大概需要5分钟。
内容图文
我在将C .dll函数转换为C#时遇到问题.
函数是这样的:
void funct(void*(*handler)(void*));
我认为这意味着将指针传递给采用void指针的函数并返回void指针,如此处所述:
我想做的是在C#中做同样的事情,但是我知道如何做.我尝试使用委托,但是我既不确定如何使用,也不确定他们是否可以执行我尝试做的事情.
谢谢您的帮助!
编辑:
这是register_message_handler和message_handler的C函数:
void register_message_handler(void*(*handler)(void*));
void *message_handler(void *raw_message);
编辑:
xanatos在下面有确切的解释并转换为C#.谢谢一吨xanatos!
解决方法:
void funct(void*(*handler)(void*));
是一个接受指针并返回指针的函数.
在C#中,它将是:
IntPtr MyFunc(IntPtr ptr);
因此,您将需要一个类似的委托:
public IntPtr delegate MessageHandlerDelegate(IntPtr ptr);
[DllImport("mydll.dll")]
public static extern void register_message_handler(MessageHandlerDelegate del);
请注意,P / Invoke(调用本地方法)是Action …和Func< ...>委托不起作用,您必须构建“特定”委托.
但是要调用它有点复杂,因为您必须保存委托的“副本”,以便如果C函数随时调用此方法,则此副本仍是“有效的”并且不是GC(请参阅参考资料).例如https://stackoverflow.com/a/5465074/613130).最常见的方法是将所有内容封装在一个类中,然后将副本放入该类的属性/字段中:
class MyClass
{
public delegate IntPtr MessageHandlerDelegate(IntPtr ptr);
[DllImport("mydll.dll")]
public static extern void register_message_handler(MessageHandlerDelegate del);
[DllImport("mydll.dll")]
public static extern IntPtr message_handler(IntPtr message);
public MessageHandlerDelegate Del { get; set; }
public void Register()
{
// Make a copy of the delegate
Del = Handler;
register_message_handler(Del);
}
public IntPtr Handler(IntPtr ptr)
{
// I don't know what ptr is
Console.WriteLine("Handled");
return IntPtr.Zero; // Return something sensible
}
}
请注意,如果您使用IntPtr,则不需要不安全的对象.
如果要将message_handler传递给register_message_handler,最安全的方法是
// Make a copy of the delegate
Del = message_handler;
register_message_handler(Del);
有可能您可以直接做没有,没有检查
register_message_handler(message_handler);
而CLR将解决此问题,但是我不确定这一点……我无法轻松对其进行测试,也不会这样做. (如果要测试它,请在register_message_handler之后添加GC.Collect().如果过了一段时间,您收到CallbackOnCollectedDelegate错误,那么您知道您将无法执行:-))
嗯…检查.您不能执行原始的register_message_handler(message_handler),必须使用MyClass.
要特别注意:最好始终在函数指针中指定调用约定C端和C#端. C#使用stdcall,而C使用cdecl.在x86模式下,您会遇到非常糟糕的静默崩溃(在x64中,只有一个调用约定)
void __stdcall register_message_handler(void* (__stdcall *handler)(void*));
void * __stdcall message_handler(void *raw_message);
和C#端
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr MessageHandlerDelegate(IntPtr ptr);
[DllImport("Win32Project1.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void register_message_handler(MessageHandlerDelegate del);
[DllImport("Win32Project1.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr message_handler(IntPtr message);
(或无处不在的cdecl)
内容总结
以上是互联网集市为您收集整理的在C#中传递函数指针全部内容,希望文章能够帮你解决在C#中传递函数指针所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。