c++与C# winform的消息通讯--(结构体与byte数组的使用)
2014-07-26 23:52
441 查看
近期正在做一个蓝牙驱动的使用程序,其中有一块从c++发送数据到C#的部分,网上查了很多资料,大多都是介绍如何通过调用函数获取用户数据。并且在消息发送中,很少介绍如何发送一个结构体,并且结构体里面有
byte数组(硬件开发常用)等如何进行处理。
首先c++里面要建立一个dll文件:
/*****************************************************************/
c#语言部分
1、在这次处理的时候,在消息发送过来的数据遇到过是乱码的情况,可能是字符串的编码格式有问题( CharSet = CharSet.Ansi)也可能是长度定义的不够 托管与非托管之间创建了一个数据块,然后他将两个数据块进行对齐,然后将数据读取出来转变成我们想要的结构。
2、查过很多地方,好像在介绍c++post数据的时候,很少有介绍到用Byte数组的,而byte数组是在很多硬件设计(串口、usb)下使用比较多的 他的UnmanagedType应该是ByValArray
3、 dataInfo h = (dataInfo)Marshal.PtrToStructure((IntPtr)RecvData.lpData, typeof(dataInfo));//这句和上面的一句就已经将数据进行转换了 在这句上,我发现(IntPtr)RecvData.lpData,其实发送的就是pInfo的地址,当时想,我要是直接从dll发送给from不就可以了? 结果测试了一下,不行,提示内存错误。应该是托管代码与非托管代码之间为了数据交互增加的一个接口,一般不允许绕过! 估计有了这样的数据传输方式,一般硬件的数据传输基本上就ok了,以后完全可以用c++写驱动,写底层接口,用c#做界面开发了!!
byte数组(硬件开发常用)等如何进行处理。
首先c++里面要建立一个dll文件:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } struct DevInfo//定义一个我自己的数据结构体 { INT32 id; char name[20]; char mac[25]; BYTE data[100]; }; extern "C" __declspec(dllexport) int sendTest(INT32 msg)//测试用的发布函数,这个int32参数一点作用都没有 { DevInfo *pinfo=new DevInfo(); pinfo->id=999; sprintf(pinfo->name,"myDevice"); sprintf(pinfo->mac,"19:4x:3a:4a"); for (int i = 0; i < 100; i++) { pinfo->data[i]=(BYTE)(0x40+i); } COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值,COPYDATASTRUCT,这个也是系统自己定义的*/ cpd.dwData = 959; //定义一个标示符(我这里没有用到) cpd.cbData = sizeof(DevInfo); cpd.lpData = pinfo; //将指针的地址通过消息发送 HWND handle2=::FindWindowA(NULL,(LPCSTR)"Form1");//获取窗口的句柄 ::SendMessageA(handle2,WM_COPYDATA,(WPARAM)13,(LPARAM)&cpd); //这个地方必须要用sendMessageA,如果用post的话,则可能会出现数据还没有发送完 //系统就把定义的DevInfo 给清理掉了 std::cout<<"发送数据消息"<<WM_COPYDATA<<std::endl; delete pinfo; return 12; }
/*****************************************************************/
c#语言部分
namespace Test { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private const int WM_COPYDATA = 0x004A;//自己定义一个消息是必须的了 [DllImport("BlueTooth4.dll", EntryPoint = "sendTest", CallingConvention = CallingConvention.Cdecl)] public static extern Int32 sendTest(int msg);//我们刚才执行的事件,这个是为了测试用才这样做的 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct COPYDATASTRUCT//定义数据传输的结构 { public IntPtr dwData; public int cbData; public IntPtr lpData; } //定义要传递的Struct [StructLayout(LayoutKind.Sequential)]//如果发现处理的数据有乱码的话,则在此处加上 ,CharSet = CharSet.Ansi struct dataInfo { public IntPtr id; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string name; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string mac; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)] public byte[] data; } protected override void DefWndProc(ref Message m)//开始处理消息 { switch (m.Msg) { //接收CopyData消息,读取发送过来的数据 case WM_COPYDATA: COPYDATASTRUCT copydata = new COPYDATASTRUCT(); COPYDATASTRUCT RecvData = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT)); dataInfo h = (dataInfo)Marshal.PtrToStructure((IntPtr)RecvData.lpData, typeof(dataInfo));//这句和上面的一句就已经将数据进行转换了 break; default: base.DefWndProc(ref m); break; } } } }
1、在这次处理的时候,在消息发送过来的数据遇到过是乱码的情况,可能是字符串的编码格式有问题( CharSet = CharSet.Ansi)也可能是长度定义的不够 托管与非托管之间创建了一个数据块,然后他将两个数据块进行对齐,然后将数据读取出来转变成我们想要的结构。
2、查过很多地方,好像在介绍c++post数据的时候,很少有介绍到用Byte数组的,而byte数组是在很多硬件设计(串口、usb)下使用比较多的 他的UnmanagedType应该是ByValArray
3、 dataInfo h = (dataInfo)Marshal.PtrToStructure((IntPtr)RecvData.lpData, typeof(dataInfo));//这句和上面的一句就已经将数据进行转换了 在这句上,我发现(IntPtr)RecvData.lpData,其实发送的就是pInfo的地址,当时想,我要是直接从dll发送给from不就可以了? 结果测试了一下,不行,提示内存错误。应该是托管代码与非托管代码之间为了数据交互增加的一个接口,一般不允许绕过! 估计有了这样的数据传输方式,一般硬件的数据传输基本上就ok了,以后完全可以用c++写驱动,写底层接口,用c#做界面开发了!!
相关文章推荐
- windows mobile平台中使用C#将byte数组转换为Format24bppRgb格式的图片
- 使用WM_COPYDATA消息在C++和C#程序之间互传数据
- C#通信,结构体和byte数组互转
- 使用ICE建立C++与C#的通讯
- c# 调用 c++ dll 参数为结构体数组指针
- C++带有指针数组的结构体转换为C#可用的结构体
- C#调用c++的dll,结构体数组作为引用参数的传递方式
- C++ 结构体数组的使用
- C# 与 C++交互的重要细节 结构体传递 数组传递 等 stdcall
- C#接收C/C++DLL的结构体嵌套数组及多维数组的解决方案
- C#调用C++方法,C#使用c++方法返回类或结构体
- C#调用C++方法,C#使用c++方法返回类或结构体
- 1ActiveMQ使用 2ActiveMQC#Client实现 3ActiveMQC++Client实现通讯 4 ActiveMQJavaClient实现
- C#调用C++生成的dll,参数有结构体数组
- 使用C#将文件以Byte数组的形式读入内存
- 使用ICE建立C++与C#的通讯
- C#调用c++Dll 结构体数组指针的问题
- C#调用C++方法,C#使用c++方法返回类或结构体
- C#调用C++方法,C#使用c++方法返回类或结构体。
- [问题]C# 结构体对齐:如何将变长byte数组对齐