C#传委托给C语言的函数指针调用问题

C代码如下:
#include "stdio.h"
__declspec(dllexport) int Call(int (*qq)(int num),char * str)
{    
    printf(str);
    return qq(123);
}

多次验证发现在C#中传委托给C中的函数指针,如果委托不带参数则都能成功运行,但是委托一带参数不管是int参数还是string参数或者其他参数,都会报“ 尝试读取或写入受保护的内存。这通常指示其他内存已损坏”的错误,或是“读取位置0x......  时发生访问冲突”的错误。

这些都是指针的访问出现了问题。

找了一天才找到解决方法:在C#的委托声明上加[UnmanagedFunctionPointer(CallingConvention.Cdecl)],正确调用如下:

复制代码
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate int MyDeg(int num);
    class Program
    {
        static void Main(string[] args)
        {
            
            try
            {
                MyDeg myd = new MyDeg(FF);
                Console.WriteLine(Call(myd, "helloworld"));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        static int FF(int num)
        {
            Console.WriteLine(num);
            return num + 1;

        }

        [DllImport("my.dll", EntryPoint = "Call")]
        public extern static int Call(MyDeg mm ,string  str);
    }
复制代码

参考:C#传委托给C的函数指针调用问题

其他参考:
  很多的Dll都是C和C++写的,那么如果C#想要调用Dll中的函数怎么办,尤其是Dll函数其中一个参数是函数指针的,即里面有回调函数的用C#怎么实现?
  C中的回调函数在C#中有中特殊的处理方式叫委托,即要实现的回掉函数委托给另一个和它返回值类型以及函数参数类型、数量一样的方法来实现。
链接:C#委托实现C++ Dll中的回调函数

另外需要注意:要防止定义的委托被gc回收,参考
托管C++随笔二:回调函数
一般的报错信息是:对“xxxx::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用。


 

posted @   peterYong  阅读(460)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2021-06-10 Mac使用
2019-06-10 FTP与HTTP上传文件的对比
2019-06-10 【FTP】Wireshark学习FTP流程
点击右上角即可分享
微信分享提示