转载:http://www.cnblogs.com/lizhaoduo/p/3870809.html

近期正在做一个蓝牙驱动的使用程序,其中有一块从c++发送数据到C#的部分,网上查了很多资料,大多都是介绍如何通过调用函数获取用户数据。并且在消息发送中,很少介绍如何发送一个结构体,并且结构体里面有

byte数组(硬件开发常用)等如何进行处理。

首先c++里面要建立一个dll文件:

 1 BOOL APIENTRY DllMain( HMODULE hModule,    DWORD  ul_reason_for_call,LPVOID lpReserved)2 {3     switch (ul_reason_for_call)4     {5     case DLL_PROCESS_ATTACH:6     case DLL_THREAD_ATTACH:7     case DLL_THREAD_DETACH:8     case DLL_PROCESS_DETACH:9         break;
10     }
11     return TRUE;
12 }
13
14 struct DevInfo//定义一个我自己的数据结构体
15 {
16     INT32 id;
17     char name[20];
18     char mac[25];
19     BYTE  data[100];
20 };
21
22 extern "C" __declspec(dllexport) int sendTest(INT32 msg)//测试用的发布函数,这个int32参数一点作用都没有
23 {
24     DevInfo *pinfo=new DevInfo();
25     pinfo->id=999;
26     sprintf(pinfo->name,"myDevice");
27     sprintf(pinfo->mac,"19:4x:3a:4a");
28
29     for (int i = 0; i < 100; i++)
30     {
31         pinfo->data[i]=(BYTE)(0x40+i);
32     }
33
34     COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值,COPYDATASTRUCT,这个也是系统自己定义的*/
35     cpd.dwData = 959;               //定义一个标示符(我这里没有用到)
36     cpd.cbData = sizeof(DevInfo);
37     cpd.lpData = pinfo;             //将指针的地址通过消息发送
38
39     HWND handle2=::FindWindowA(NULL,(LPCSTR)"Form1");//获取窗口的句柄
40
41     ::SendMessageA(handle2,WM_COPYDATA,(WPARAM)13,(LPARAM)&cpd);
42
43     //这个地方必须要用sendMessageA,如果用post的话,则可能会出现数据还没有发送完
44     //系统就把定义的DevInfo 给清理掉了
45
46     std::cout<<"发送数据消息"<<WM_COPYDATA<<std::endl;
47     delete pinfo;
48
49     return 12;
50 }

/*****************************************************************/
c#语言部分

 1 namespace Test2 {3     public partial class Form1 : Form4     {5         public Form1()6         {7             InitializeComponent();8         }9
10         private const int WM_COPYDATA = 0x004A;//自己定义一个消息是必须的了
11
12         [DllImport("BlueTooth4.dll", EntryPoint = "sendTest", CallingConvention = CallingConvention.Cdecl)]
13         public static extern Int32 sendTest(int msg);//我们刚才执行的事件,这个是为了测试用才这样做的
14
15
16         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
17         public struct COPYDATASTRUCT//定义数据传输的结构
18         {
19             public IntPtr dwData;
20             public int cbData;
21             public IntPtr lpData;
22         }
23
24         //定义要传递的Struct
25        [StructLayout(LayoutKind.Sequential)]//如果发现处理的数据有乱码的话,则在此处加上 ,CharSet = CharSet.Ansi
26        struct dataInfo
27        {
28            public IntPtr id;
29
30             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
31            public string name;
32
33            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)]
34            public string mac;
35
36            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
37            public byte[] data;
38        }
39
40         protected override void DefWndProc(ref Message m)//开始处理消息
41         {
42             switch (m.Msg)
43             {
44                 //接收CopyData消息,读取发送过来的数据
45                 case WM_COPYDATA:
46                  COPYDATASTRUCT copydata = new COPYDATASTRUCT();
47                  COPYDATASTRUCT RecvData = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
48                  dataInfo h = (dataInfo)Marshal.PtrToStructure((IntPtr)RecvData.lpData, typeof(dataInfo));//这句和上面的一句就已经将数据进行转换了
49                    break;
50                 default:
51                     base.DefWndProc(ref m);
52                     break;
53             }
54
55         }
56     }
57 }

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#做界面开发了!!

转载于:https://www.cnblogs.com/y114113/p/6289784.html

c++与C# winform的消息通讯--(结构体与byte数组的使用)相关推荐

  1. C#通信,结构体和byte数组互转

    在C#进行UDP或者TCP/IP通信时,经常要用到byte数组来传递信息.一开始,我是使用BitConverter和Encoding来进行转换.后来经过大神指导,其实一切不必那么麻烦.只需将要发送的信 ...

  2. C#结构体和字节数组的转换

    在写C#TCP通信程序时,发送数据时,只能发送byte数组,处理起来比较麻烦不说,如果是和VC6.0等写的程序通信的话,很多的都是传送结构体,在VC6.0中可以很方便的把一个char[]数组转换为一个 ...

  3. C# 结构体转字节数组

    (1)定义结构体 public struct Data1     {         [MarshalAs(UnmanagedType.ByValArray)]         public char ...

  4. day4-项目软硬件环境分析和通讯结构体

    硬件部分 fs4412开发板 3*zigbee模块 摄像头 gprs(用于通讯) fs4412部分 3个USB接口分别用于zigbee协调器.usb摄像头.gprs模块 陀螺仪与加速计作为数据采集端, ...

  5. C#:钩子、委托、匿名、事件、结构体转字节数组、多线程操纵控件、UDP

    事件 C#事件分为几个步骤: 定义事件 定义处理函数 为事件添加处理函数 激活事件 事件被激活后自动调用处理函数. public event messagehandleer shenzhijiangl ...

  6. matlab单元数组与结构体的区别,MATLAB中的结构体和单元数组

    MATLAB中的结构体和单元数组 一.结构: x.real=10 x.imag=5 增加字段 x.scale=1 使用struct函数 s=struct('field1',values1,'field ...

  7. 【VS开发】【编程开发】【C/C++开发】结构体中的数组与指针的内存分配情况说明...

    [VS开发][编程开发][C/C++开发]结构体中的数组与指针的内存分配情况说明 标签:[VS开发] [编程开发] 主要是疑惑在结构体定义的数组的内存空间与指针动态分配的内存空间,在地址上连续性.以及 ...

  8. Golang之空结构体和零长数组的实践

    空结构体和零长数组(两个复合类型)都仅仅是一个占位符,不占用空间,这里编译器进行了优化,如果结构体或数组的unsafe.sizeof=0则直接返回zerobase. // 必须用key来初始化结构体 ...

  9. go语言json字符串解析为结构体数组,结构体指针的数组

    废话不多说直接上效果图 完整代码如下 package main import ("encoding/json""fmt" ) // 结构体定义 type rob ...

最新文章

  1. 数据库还原失败System.Data.SqlClient.SqlError: 无法执行 BACKUP LOG,因为当前没有数据库备份...
  2. 编程之美——买书问题:贪心算法
  3. ADO学习(九)如何阅读ADO文档
  4. ASP.NET 开发者 开始学习ASP.NET Core 2吧
  5. 零的突破!炸出圈的“女娲补天”教授获国家杰青!
  6. C# String和string的区别
  7. 1.1.0-简介-P7-Raft、Zab
  8. python创建二维数组的方法_Python创建二维数组的正确姿势
  9. 《设计模式详解》结构型模式 - 适配器模式
  10. 程序员别埋头苦干了,花时间学点薪资谈判技巧多赚一个亿可好?
  11. [十]JavaIO之FilterInputStream FilterOutputStream
  12. SQL查询语句精华使用简要
  13. js学习笔记——函数定义
  14. ubuntu上matlab2014a修改成windows方式快捷键
  15. jQuery炫酷特效之遮罩移动效果
  16. 图(一)| BFS与DFS算法 - Python实现
  17. Synchronized 用法以及和ReetrantLock的区别
  18. int、long、long long、unsigned int、_int64的取值范围(与不同位数的编译器有关)
  19. 计算机表格按性别排列,excel表格数据男女分类-Excel 按性别(男女)排序
  20. 苹果cmsv10模板MXone自适应模板

热门文章

  1. layui.table.render设置自定义高度高度
  2. 一文看懂Python(八)-----内置高阶函数用法总结
  3. UNIX再学习 -- 错误和警告
  4. 10 Lessons Learned Doing ICOs
  5. 用Android Studio调试Framework层代码
  6. Android短信发送流程之长短信发送(原)
  7. ActivityManagerService简要分析
  8. intellij idea 2018 license 可用无废话
  9. 树莓派linux系统识别u盘启动,树莓派Raspberry Pi实战之命令行下实现USB存储设备自动挂载...
  10. python里compile的作用_Python代码中compile()函数具有哪些功能呢?