近期正在做一个蓝牙驱动的使用程序,其中有一块从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[];
char mac[];
BYTE data[];
}; extern "C" __declspec(dllexport) int sendTest(INT32 msg)//测试用的发布函数,这个int32参数一点作用都没有
{
DevInfo *pinfo=new DevInfo();
pinfo->id=;
sprintf(pinfo->name,"myDevice");
sprintf(pinfo->mac,"19:4x:3a:4a"); for (int i = ; i < ; i++)
{
pinfo->data[i]=(BYTE)(0x40+i);
} COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值,COPYDATASTRUCT,这个也是系统自己定义的*/
cpd.dwData = ; //定义一个标示符(我这里没有用到)
cpd.cbData = sizeof(DevInfo);
cpd.lpData = pinfo; //将指针的地址通过消息发送 HWND handle2=::FindWindowA(NULL,(LPCSTR)"Form1");//获取窗口的句柄 ::SendMessageA(handle2,WM_COPYDATA,(WPARAM),(LPARAM)&cpd); //这个地方必须要用sendMessageA,如果用post的话,则可能会出现数据还没有发送完
//系统就把定义的DevInfo 给清理掉了 std::cout<<"发送数据消息"<<WM_COPYDATA<<std::endl;
delete pinfo; return ;
}

/*****************************************************************/
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 = )]
public string name; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string mac; [MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
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#做界面开发了!!

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

  1. c# 调用c++sdk时结构体与byte数组互转

    /// <summary> /// 由结构体转换为byte数组 /// </summary> public static byte[] StructureToByte<T ...

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

    在通信过程中,一般我们都会操作到字节数组.特别是希望在不同语言编程进行操作的时候. 虽然C#提供了序列化的支持,不用字节数组也行.但操作字节数组肯定会碰到.   一般都会采用结构来表示字节数组.但结构 ...

  3. (一)一个工作任务引起的乱战——c#中结构体与byte[]间相互转换

    一个工作任务涉及到c#与c++系统间的udp通信,处理了蛮长时间没有完成任务,但是期间接触到不少小知识点.本人是初接触c#,c++语言没有接触过.可能写的东西都很小儿科,暂且记录下来当工作日记把. 先 ...

  4. c#中关于结构体和字节数组转化

    最近在使用结构体与字节数组转化来实现socket间数据传输.现在开始整理一下.对于Marshal可以查阅msdn,关于字节数组与结构体转代码如下: using System; using System ...

  5. 使用unsafe.Pointer将结构体转为[]byte

    package main import ( "fmt" "unsafe" ) type TestStructTobytes struct { data int6 ...

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

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

  7. C语言结构体中字符数组的问题

    第一个程序 #include <stdio.h> #include <string.h> typedef struct student { char name[10]; int ...

  8. c动态分配结构体二维数组

    这个问题我纠结了蛮久了,因为前面一直忙(自己也懒了点),所以没有能好好研究这个.希望这篇文章能够帮助你们. #include <stdio.h> #include <stdlib.h ...

  9. c结构体里的数组与指针

    /* 訪问成员数组名事实上得到的是数组的相对地址.而訪问成员指针事实上是相对地址里的内容 */ struct buf_str { int length; char buf[0]; }; struct ...

随机推荐

  1. jQuery对象与dom对象相互转换jQuery对象与dom对象相互转换

    转至:http://www.chinaz.com/design/2010/0309/108144.shtml 刚开始学习jQuery,可能一时会分不清楚哪些是jQuery对象,哪些是DOM对象.至于D ...

  2. XML与XHTML

    什么是XML XML的基本格式 XML的定义文档 HTML5的文档定义 XHTML1.0的文档定义 XHTML1.0标记格式 12.1 什么是XML XML中文翻译为可扩展标记语言,顾名思义,它比HT ...

  3. 《Effect Java》学习笔记1———创建和销毁对象

    第二章 创建和销毁对象 1.考虑用静态工厂方法代替构造器 四大优势: i. 有名称 ii. 不必在每次调用它们的时候都创建一个新的对象:   iii. 可以返回原返回类型的任何子类型的对象: JDBC ...

  4. 最新版postgresql+pgboucer安装

    安装postgresql: wget https://pgbouncer.github.io/downloads/files/1.7.2/pgbouncer-1.7.2.tar.gz wget htt ...

  5. 使用jdom操作xml文件 去除子节点带有命名空间

    package com.soft.common; import java.util.HashMap; import java.util.Map; import org.jdom2.Namespace; ...

  6. 订阅基础:RSS、ATOM、FEED、聚合、供稿、合烧与订阅

    很多网友对这类名词概念非常陌生,如果没用过FEED订阅,肯定还会对诸多网站显示的FEED聚合.订阅.ATOM等等非常郁闷,虽然这几个名字间的很多并非并列关系,天缘只是有意把它们放到一起,方便对比参考, ...

  7. vim: 自己定义颜色主题(colorscheme)

    命令模式下输入 :hi[ghlight] 能够看到当前vim的着色风格 命令模式下输入 :sy[ntax] 能够看到当前语法加亮模式,当文档的文字与列表里的正則表達式匹配时,vim会给文字着色.应用缩 ...

  8. 各种会义PPT

    http://vdisk.weibo.com/s/dBzv2siaHK2H http://vdisk.weibo.com/wap/u/3460619722 https://yunqi.aliyun.c ...

  9. careercup-树与图 4.4

    4.4 给定一棵二叉树,设计一个算法,创建含有某一深度上所有结点的链表(比如,若一棵树的深度为D,则会创建D个链表). 类似于leetcode:Populating Next Right Pointe ...

  10. C# 以ThreadStart方式实现多线程

      3.1 使用ThreadStart委托 这 里先以一个例子体现一下多线程带来的好处,首先在Message类中建立一个方法ShowMessage(),里面显示了当前运行线程的Id,并使用 Threa ...