复杂结构体的传递

1. 输出参数,结构体作为指针传出

非托管部分代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

typedef struct

{

    char name[20];

    int age;

    double scores[32];

}Student;

//Class中包含结构体数组类型

typedef struct

{

    int number;

    Student stedents[50];

}Class;

JNAAPI int GetClass(Class *pClass,int len)

{

    for(int i = 0; i < len; i++)

    {

        pClass[i].number = i;

        for(int j = 0; j< 50; j++)

        {

            //把name中的前20个字节用0代替

            memset(pClass[i].stedents[j].name, 0, 20);

            //给每个同学命名

            sprintf(pClass[i].stedents[j].name, "name_%d_%d", i, j);

            pClass[i].stedents[j].age = j % 2 == 0 ? 15:20;

        }//for

    }//for

    return 0;

}

  

上面DLL 的导出函数要求传递的参数为它自定义的Class结构体数组, 那么我们在C#调用它时也要自定义对应的结构体了,

我们可以定义为如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

[StructLayout(LayoutKind.Sequential)]

struct Student

{

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]

    public string name;

    public int age;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]

    public double[] scores;

}

[StructLayout(LayoutKind.Sequential)]

struct Class

{

    public int number;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]

    public Student[] students;

}

  需要注意的是,这2个结构体中的数组大小一定要跟C++中的限定一样大小哦,接下来如何使用这个API来正确的获取数据呢,大多数人可能想到像这样的处理方式:

1

2

3

4

Class myclass = new Class();

IntPtr ptr=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Class)));

GetClass(ptr);

Marshal.FreeHGlobal(ptr);

  

没错,这样的处理是没问题的,但是我们的API的参数是Class数组,这种处理方式只是传递一个Class结构体参数,所以这种方式在这里就不太合适了,!

那大家就想到先Class[] myclass = new Class[MaxClass]; 然后在用Marshal.AllocHGlobal 来获取myclass 数据的指针,

其实这样也是错的, 因为 Class结构中包含了,不能直接封送的Student结构,所以无论如何上面的想法是错误的!

那要怎么办呢,其实很简单,就是先分配一段非托管内存,并调用API后,再将非托管内容数据读取到托管结构体数据中!

示例演示代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// 接口定义  

[DllImport("CSharpInvokeCpp_CppDemo.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern int GetClass(IntPtr pv, int len);

//复杂结构体传递测试代码

int size = Marshal.SizeOf(typeof(Class)) * 50;

IntPtr pBuff = Marshal.AllocHGlobal(size);

CppDLL.GetClass(pBuff, 50);

Class[] pClass = new Class[50];

for (int i = 0; i < 50; i++)

{

    IntPtr pr = new IntPtr(pBuff.ToInt64() + Marshal.SizeOf(typeof(Class)) * i);

    pClass[i] = (Class)Marshal.PtrToStructure(pr, typeof(Class));

}

Marshal.FreeHGlobal(pBuff);

c# 与c++接口间调用时传递结构体相关推荐

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

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

  2. 《带你学C带你飞》—— SE44传递结构体变量和结构体指针

    使用结构体嵌套.结构体函数来写书的信息的程序 #include <stdio.h>struct Date {int year;int month;int day; };struct Boo ...

  3. matlab 不同函数间传递结构体数据_matlab 结构体struct函数使用方法

    1.struct函数直接定义 查阅文档是这样的:struct(field1,value1,field2,value2,.....) 上面这个格式很重要记住 field1和field2称为这个结构体的字 ...

  4. c语言如何传递结构体指针,注意使用结构体指针给函数传递参数。

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 为了增加参数调用的灵活性,可以利用结构体指针传递多个不同的参数进入C语言函数体. 最著名的例子就是用Win32API HANDLE CreateThrea ...

  5. qt socket 传递结构体 结构体中有list_计算机网络应用--Socket编程实验(二)

    本节关于socket部分函数库列表,具体基于socket的实例实现代码见下节.给出基于winSocket的简单websever实例. 2.1 WSAStartup() [函数原型] int WSASt ...

  6. 信号与槽QVariant传递结构体指针

    目录 一.使用情景 二.使用步骤 1.全局宏定义 2.示例: 一.使用情景 1.在使用带参数的信号与槽的时候,有时需要传递不常见的结构或者自定义结构,此时需要用到QVariant来传参,如果想传递多个 ...

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

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

  8. c语言调用dll实例 结构体传参,C# 调用Dll 传递字符串指针参(转)

    java -日期处理 1. 计算某年某月份 总有多少个周,每周的开始和结束时间? 思路:1.计算出本月实际的总天数 2.循环每一天,判断这天是否是 周日(1),如果是,周数加1,再次判断是否是月的第一 ...

  9. 传递结构体变量解决方案,资料整理一

    2019独角兽企业重金招聘Python工程师标准>>> 1.activex控件返回BSTR* 的方法 用到了 COleDataObject::GetData BOOL GetData ...

最新文章

  1. android AIDL IPC深入分析
  2. Linux终端关闭屏幕显示,使用命令行关闭监视器
  3. rm排除某个文件进行删除
  4. docker d盘_windows修改docker的默认存放位置
  5. python如何打开一个大文件?
  6. Codeforces Round #639 (Div. 2)(AB)
  7. 【公众号系列】SAP S/4 HANA的移动平均价
  8. 零基础入门深度学习(5) - 循环神经网络
  9. JNIWrapper控件发布v3.8.4版本
  10. PLSQL Developer报“动态执行表不可访问,本会话的自动统计被禁止”的解决方案...
  11. shell sort result to self
  12. Servlet+JSP分页
  13. 【云周刊】第121期:图管够!灌篮高手、女儿国…阿里日,这帮程序员太会玩了!...
  14. 如何做一个简单的类似qq网页版等的聊天网页
  15. 基于光流和RNN的长视频微表情检测
  16. 从零开始学习区块链技术
  17. ISM330DHCXTR IMU-惯性测量单元 工业物联网 运动传感器
  18. mysql distinct 优化_Mysql应用分析MySQL中优化distinct的技巧
  19. 理解色彩与相机内图像处理流程——流程详解
  20. android 双屏壁纸,高清全面屏双屏壁纸

热门文章

  1. HightChart数据提示框(Tooltip)
  2. 无法重现一些战利品_消除战利品神话
  3. 万字梳理计算机网络(最全)
  4. android 5.1.1开机优化(framework层)
  5. AI系统能否理解3D现实世界?Facebook做了这些研究
  6. 立个Flag,掌握三种通信中用的DL网络
  7. QScintilla的各种颜色字体等设置
  8. 【蓝桥杯 迷宫 2019省赛javaA组】BFS解法该死的Excel竟如此甜美
  9. Spark Web UI详解
  10. 打开html文件 跳转到hao123,我家电脑网页老是打开hao123它就自动跳转成别的网页.怎么办?...