http://blog.csdn.net/jadeflute/article/details/5684687

C#调用c++dll文件是一件很麻烦的事情,首先面临的是数据类型转换的问题,相信经常做c#开发的都和我一样把学校的那点c++底子都忘光了吧(语言特性类)。

网上有一大堆得转换对应表,也有一大堆的转换实例,但是都没有强调一个更重要的问题,就是c#数据类型和c++数据类型占内存长度的对应关系。

如果dll文件中只包含一些基础类型,那这个问题可能可以被忽略,但是如果是组合类型(这个叫法也许不妥),如结构体、类类型等,在其中的成员变量的长度的申明正确与否将决定你对dll文件调用的成败。

如有以下代码,其实不是dll文件的源码,而是厂商给的c++例子代码

c++中的结构体申明

[c-sharp] view plaincopy

typedef struct
{
unsigned char Port;
unsigned long Id;
unsigned char Ctrl;
unsigned char pData[8];
}HSCAN_MSG;

c++中的函数申明(一个c++程序引用另一个c++的dll文件)

[c-sharp] view plaincopy
  1. extern "C" int _stdcall HSCAN_SendCANMessage(unsigned char nDevice,unsigned char nPort,HSCAN_MSG *msg,int nLength);

c++中的调用:

[c-sharp] view plaincopy

....
HSCAN_MSG msg[100];
.....
HSCAN_SendCANMessage(m_nDevice,m_nPort,msg,nFrames);

由上述代码可见,msg是个结构体的数组。

下面是我的c#的代码

c#结构体申明:(申明成)

[c-sharp] view plaincopy

[StructLayout(LayoutKind.Sequential)]
public struct HSCAN_MSG
{
    // UnmanagedType.ByValArray, [MarshalAs(UnmanagedType.U1)]这个非常重要,就是申明对应类型和长度的
[MarshalAs(UnmanagedType.U1)]
public byte Port;
[MarshalAs(UnmanagedType.U4)]
public uint nId;
[MarshalAs(UnmanagedType.U1)]
public byte nCtrl;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] pData;
};

public struct CThostFtdcReq
{
///用户代码
[MarshalAs(UnmanagedType.LPStr, SizeConst = 16)]
public string TThostFtdcUserIDType;
///密码
[MarshalAs(UnmanagedType.LPStr, SizeConst = 41)]
public string TThostFtdcUserIDType;
};

c#函数申明

[c-sharp] view plaincopy 

[DllImport("HS2106API.dll")]
public static extern int HSCAN_SendCANMessage(
byte nDevice, byte nPort, HSCAN_MSG[] pMsg, int nLength);

C#函数调用

[c-sharp] view plaincopy

HSCAN_MSG[] msg = new HSCAN_MSG[1]; //发送缓冲区大小可根据需要设置;
for (int yy = 0; yy < msg.Length; yy++)
{
msg[yy] = new HSCAN_MSG();
}
    //...结构体中的成员的实例化略
    HSCAN_SendCANMessage(0x0, 0x0, msg, 1)

那些只能用指针不能用结构体和类的地方

c++中的结构体申明

[c-sharp] view plaincopy

typedef struct
{
unsigned char Port;
unsigned long Id;
unsigned char Ctrl;
unsigned char pData[8];
}HSCAN_MSG;

c++中的函数申明(一个c++程序引用另一个c++的dll文件)

[c-sharp] view plaincopy
  1. extern "C" int _stdcall HSCAN_SendCANMessage(unsigned char nDevice,unsigned char nPort,HSCAN_MSG *msg,int nLength);

c#中的结构体申明:

[c-sharp] view plaincopy

[StructLayout(LayoutKind.Sequential)]
public struct HSCAN_MSG
{
[MarshalAs(UnmanagedType.U1)]
public byte Port;
/// <summary>
/// 节点标识,nEFF=1 时(扩展帧),为29 位nEFF=0(标准帧)时,为11 位;
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public uint nId;
[MarshalAs(UnmanagedType.U1)]
public byte nCtrl;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] pData;
};

c#函数的调用:包含使用指针IntPtr替代结构体数组和读取IntPtr的方法

[c-sharp] view plaincopy

HSCAN_MSG[] msg1 = new HSCAN_MSG[10];
for (int i = 0; i < msg1.Length; i++)
{
msg1[i] = new HSCAN_MSG();
msg1[i].pData = new byte[8];
}
IntPtr[] ptArray = new IntPtr[1];
ptArray[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HSCAN_MSG)) * 10);
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HSCAN_MSG)));
Marshal.Copy(ptArray, 0, pt, 1);

int count = HSCAN_ReadCANMessage(0x0, 0,pt, 10);

textBoxStatus.Text += "/r/n" + "读取0口:" + count.ToString() + "帧数据";
for (int j = 0; j < 10; j++)
{
msg1[j] =
(HSCAN_MSG)Marshal.PtrToStructure((IntPtr)((UInt32)pt+ j * Marshal.SizeOf(typeof(HSCAN_MSG)))
, typeof(HSCAN_MSG));
textBoxStatus.Text += "/r/n收到0口" + Convert.ToByte(msg1[j].pData[0]).ToString()
+ "|" + Convert.ToByte(msg1[j].pData[1]).ToString()
+ "|" + Convert.ToByte(msg1[j].pData[2]).ToString()
+ "|" + Convert.ToByte(msg1[j].pData[3]).ToString()
+ "|" + Convert.ToByte(msg1[j].pData[4]).ToString()
+ "|" + Convert.ToByte(msg1[j].pData[5]).ToString()
+ "|" + Convert.ToByte(msg1[j].pData[6]).ToString()
+ "|" + Convert.ToByte(msg1[j].pData[7]).ToString();
}

转载于:https://www.cnblogs.com/carl2380/archive/2012/06/05/2536635.html

C#调用c++Dll结构体数组指针的问题相关推荐

  1. C 语言结构体数组指针以及函数

    结构体数组指针 指针变量可以指向一个结构体数组,这时指针变量的值是整个数组的首地址. 设 ps 为指向结构体数组的指针变量,则 ps 也指向该结构体数组的第 0个元素,ps+1 指向第一个元素,ps+ ...

  2. 【结构体】 结构体引用、结构体数组指针、包含结构的结构体

    目录 一.概念.变量的定义 初识结构体 结构体变量的定义.引用结构体类型的初始化 二.结构体的数组 认识结构体数组 初始化结构体数组 三.结构体指针 初识结构体指针 指向结构体数组的指针 结构体作为函 ...

  3. 【c语言】结构体详解 | 结构体数组/指针

    创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>

  4. C#调用C++DLL传递结构体数组的终极解决方案

    在项目开发时,要调用C++封装的DLL,普通的类型C#上一般都对应,只要用DllImport传入从DLL中引入函数就可以了.但是当传递的是结构体.结构体数组或者结构体指针的时候,就会发现C#上没有类型 ...

  5. 【C语言】结构体指针与结构体数组

    目录 一.结构体指针 二.结构体数组 1.结构体数组的定义 2.结构体数组的初始化 3.结构体数组的引用 4.结构体数组指针 一.结构体指针 与一般指针类似结构体也可以使用结构体指针进行引用使用.结构 ...

  6. C语言结构体的定义与使用、结构体数组、指向结构体的指针(有代码详解)

    1.结构体的定义与使用 结构体是一种构造数据类型 把不同类型的数据组合成一个整体 结构体的定义形式: struct 结构体名{结构体所包含的变量或数组 }; 结构体是一种集合,它里面包含了多个变量或数 ...

  7. 在函数中利用scanf为结构体数组赋值

    结构体数组指针作为函数参数,通过数组的首地址与偏移量对结构体数组进行scanf的赋值,在函数中通过指针间接访问到其指向的内存 程序当中,编写函数,输入5个学号(int),5个姓名(字符串),5个成绩数 ...

  8. C语言结构体指针(指向结构体的指针)详解

    当一个指针变量指向结构体时,我们就称它为结构体指针.C语言结构体指针的定义形式一般为: struct 结构体名 *变量名; 下面是一个定义结构体指针的实例: //结构体 struct stu{ cha ...

  9. c语言结构体函数排序,(为什么不能给分?)结构体数组插入排序的函数有关问题,...

    当前位置:我的异常网» C语言 » (为什么不能给分?)结构体数组插入排序的函数有关 (为什么不能给分?)结构体数组插入排序的函数有关问题, www.myexceptions.net  网友分享于:2 ...

  10. c语言调用dll实例 结构体传参,Matlab调用Dll,对于自定义结构体数组如何传参? - 程序语言 - 小木虫 - 学术 科研 互动社区...

    %[例子1] % Matlab调用DLL,整形数组传参 v = [1,22,33;44,-56,67]; pv = libpointer('int16Ptr',v); m = get(pv,'Valu ...

最新文章

  1. 不允许使用抽象类类型的对象怎么办_Java基础——面试官:你来说说抽象类和接口的区别...
  2. 智能车百度赛道培训第一弹-基础篇
  3. UA MATH571B 试验设计 Quarter 2-level析因设计
  4. 数据库mysql是什么?win10如何安装使用mysql?
  5. Dubbo自定义异常message过长解决
  6. java对象模型是什么_蓝石榴_个人博客_JVM内存结构、Java内存模型、Java对象模型...
  7. for+next()实现数组的遍历及while list each 的使用
  8. 与吴恩达并肩战斗,她是颜值爆表的 AI 科学家!
  9. PDE34 Transport equation: derivation general solution
  10. 当SEO/SEM与良知正面碰撞
  11. python线性拟合、不确定性
  12. python爬虫百度文库_百度文库爬虫,Python爬取百度文库内容输出word文档low版
  13. DIY专门制作PCB的雕刻机--所需软件
  14. 常用企业管理工具介绍
  15. 初学数据分析(一)【利用numpy实现矩阵标准化】
  16. EV SSL证书对网站的作用
  17. 苹果手机微信记录恢复最简单的恢复方法
  18. 日本护照持有者可以免签进入全球193个目的地,创下历史记录
  19. 《霜冷长河》之《壮士》----英雄归来
  20. 编译原理习题——第2章 文法和语言试卷

热门文章

  1. SparkStreaming读取本地文件进行wordCount
  2. 企业数字化转型必备利器之微服务扩展
  3. JFinal自动扫描表绑定model(包含jar包扫描)
  4. Widget实例可以添加多个并独立更新
  5. 几个jquery分发库速度测评
  6. C++学习笔记: 混合语言编程
  7. 【ABAP系列】SAP ABAP 从FTP服务器读取文件到本地
  8. python+adb实现物理按键长按(比如长按关机)
  9. linux sed用法
  10. 玉伯 对 前端的 金玉良言