C#中调用C的DLL中的回调函数,想实现消息响应机制

已经可以通过C#实现DLL中回调函数的调用,代码如下
//实时信息回调函数
[System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void REALTIME_ROADPOINT_CALLBACK(ref wayPoint_S waypoint, IntPtr arg);

[DllImport("libserviceinterface.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void rs_setcallback_realtime_roadpoint(UInt16 rshd, [MarshalAs(UnmanagedType.FunctionPtr)]REALTIME_ROADPOINT_CALLBACK CurrentPositionCallback, IntPtr arg);

//回调函数
static void CurrentPositionCallback(ref wayPoint_S waypoint, IntPtr arg)
{
PrintWaypoint(waypoint);
}

static void PrintWaypoint(wayPoint_S point)
{
Console.Out.WriteLine("pos.x={0} y={1} z={2}", point.cartPos.x, point.cartPos.y, point.cartPos.z);
}

//主函数
static void Main(string[] args)
{
//函数指针实例化
REALTIME_ROADPOINT_CALLBACK RobotPosCallBack = new REALTIME_ROADPOINT_CALLBACK(CurrentPositionCallback);
rs_setcallback_realtime_roadpoint(rshd, RobotPosCallBack, IntPtr.Zero);
//打印路点信息
while(true)
{ PrintWaypoint(waypoint);}

}

但是这种用WHILE循环读取的方式实在不好,能不能有哪位高手指点下如何改为响应消息的机制,最好直接在我的代码上修改一下,谢谢
我主要是想能够实时得到该消息,又不想依靠WHILE循环无休止的跑去获取,类似于中断的方式获取

反过来比较容易,因为C#的P/Invoke就是做这个的。但是显然C++没有关于C#代码回调的的实现,因为C++的架构从来也没考虑过还会调用C#(这种情况实在是太少见了,况且也不必要)。如果非要实现可以采用多进程,使用进程间通信。我想到的:
1.模仿linux中的管道(PIPE),产生虚拟文件,而C++阻塞直到文件产生或本身超时。这样可以实现数据交换,既能实现传数据又可以使C++程序及时得到通知。缺点就是IO密集,降低效率。
2.使用TCP通信,监听端口获取消息,这是跨平台程序通信最常用也是最正统的方法。一般是跨操作系统编程常用的,比如windows和linux ubuntu server程序进行交互。你所述情况虽然不算跨操作系统通信,但是也是跨平台了。而且想想就知道C++作为先出现的语言而且是编译型语言,调用C#托管区的函数还要设回调,其难度可想而知。
3.如果你的C++是基于winform的,可以在C#中P/Invoke调用winAPI的SendMessage发送窗体消息从而间接实现回调。
4.自然还有一些更底层的Dirty方法,比如嵌汇编更改上下文程序指针地址。。。不过不适合正统的程序,因为太Dirty啊。。。而且出错概率大。
除此之外,如果不采用多线程通信,C#的反射(reflection)特性可以参考,但是控制权依然在C#。况且C#无从知道C++的内部结构,自然难以直接调用。你想想吧,是不是这个道理~
温馨提示:内容为网友见解,仅供参考
第1个回答  2018-04-28

你这样写代码不是会疯狂输出吗,下面这样就行了,回调函数只有在需要的时候自动触发

下面是按ESC退出,把你的while循环改一下

while(Console.ReadKey(true).Key != ConsoleKey.Escape)
{
}

追问

谢谢回答,我就是希望做成消息响应的方式,但何时消息会传递过来我并不知道啊,如何才能够知道呢。你写的这个是等待我的键盘输入,而不是真的消息传递过来了啊

本回答被提问者采纳

C#中调用C的DLL中的回调函数,想实现消息响应机制
反过来比较容易,因为C#的P\/Invoke就是做这个的。但是显然C++没有关于C#代码回调的的实现,因为C++的架构从来也没考虑过还会调用C#(这种情况实在是太少见了,况且也不必要)。如果非要实现可以采用多进程,使用进程间通信。我想到的:1.模仿linux中的管道(PIPE),产生虚拟文件,而C++阻塞直到文件产生或...

如何在C#写的dll 里调用回调函数?
3.如果你的C++是基于winform的,可以在C#中P\/Invoke调用winAPI的SendMessage发送窗体消息从而间接实现回调。4.自然还有一些更底层的Dirty方法,比如嵌汇编更改上下文程序指针地址。。。不过不适合正统的程序,因为太Dirty啊。。。而且出错概率大。除此之外,如果不采用多线程通信,C#的反射(reflection)特性可...

c#-回调callback是什么原理,机制? C#
:回调函数,就是程序在执行过程中,某个条件触发后,去调用的那个函数,这需要用到函数指针,通过函数指针找到函数的入口地址,执行回调函数。在.net中,用委托来实现,委托是对函数指针的安全封装。方法(参数1,参数2,回调函数)就是把 参数1,和参数2传给 回调函数委托是对函数指针的安全封装以前的函数...

c#-回调callback是什么原理,机制? C#
回调基本过程如下:调用者(Caller)向回调函数(Callee)发出调用,被调用函数启动后,不等被调函数执行完毕,程序执行流立即返回到调用者继续执行。此时,程序中至少有两个执行流,一个是调用者执行流;另一个是被调用函数执行流同时执行。当被调函数所执行处理完毕时,被调函数反过来调用一个指定的函数...

C 调用C#dll
[DllImport("user32.dll")]public static extern int EnumWindows(CallBack x, int y);通过这种方式,可以实现与Windows API的交互。总的来说,使用DllImport关键字和相关属性可以轻松地在C#中调用C编写的DLL。需要注意函数声明与实现的匹配、参数类型和传递方式,以及回调函数的使用。使用DLL可以有效复用C...

c#调用sdk时,求教回调函数如何处理
比如SDK中有个查找所有窗口的函数:[DllImport("user32")]private static extern bool EnumWindows(DelegateEnumWindow ew, int lParam);上面的参数ew就是一个委托(回调函数),再看这个参数的声明:delegate bool DelegateEnumWindow(IntPtr hWnd, int lParam);再看调用:DelegateEnumWindow dew = new Delegate...

如何封装C++的中的回调函数供C#调用
首先用c++写一个带有回调函数的方法 Test,在此省略。接着,在c#中调用,如:[DllImport("Test.dll",ChartSet.Ansi,EntryPoint="ReadMyVideo",ExactSpelling=false,CallingConvertion=CallingConvertion.StdCall)]private static extern void Test(string fileName,CallbackDelegate callback);接下来我们再...

请教C#回调函数的调用问题
当然,在C\/CPP中我们存在指针,把函数(或成员方法,面向过程语言或支持面向过程语言中存在函数或过程的概念)指针做为参数传递即可——这是一种典型的“传址”引用的方式,在C#没有指针的情况下想完成一个传址引用,ref\/out只能传递参数变量,并不能将方法转换成地址传入另一个方法的参数(方法参数化)...

求助:C# 调用C++的dll的回调函数的结构体数组的问题,为什么只得到数组的...
正确的做法是: 在 C# 声明 lpOnRecvCardEvent 时,第二个参数应该是 IntPtr ,不是数组。由于楼主的这个 VC DLL 可能是自己写的,我没办法给出正确代码。我提供一份模拟代码做参考:--- VC DLL:StructMod.h pragma once include <Windows.h> ifndef STRUCTMOD_EXPORT define STRUCTMOD_EXPORT e...

关于如何在C#中调用C++的DLL,CLR套壳!
当DLL包含C++类时,需使用托管代码与C++类库的交互方法。对于Qt中基于信号槽机制的类,由于CLR C++不支持多继承,因此无法直接封装Qt的信号和槽机制。在C#中调用Qt类时,可通过回调函数或委托间接实现,更推荐使用回调函数,以减少不必要的封装复杂性。调用过程通常分为三个步骤:C#通过托管C++层,进而...

相似回答