首页 > 编程语言 >C++向C#传结构体

C++向C#传结构体

时间:2024-05-31 16:02:15浏览次数:18  
标签:struct C# MyStruct C++ ptr int pStruct public 结构

在写项目的时候,我需要将C++中接收到的结构体传输到我的C#项目中使用。结构体中基本是int,int[],float类型数据,这些类型在C++和C#中是一样的,可以直接传输,但是结构体怎么传输呢?下面是简单示例:

MyStruct.h

extern "C" {
#pragma pack(1)
	typedef struct _data1{  
		int id[4];  }Data1;
	typedef struct _data2{  
		int aa;}Data2;
	typedef struct _data3{  
	float cc;
	} Data3;
	typedef struct _data4{  
		int ee[4];  }Data4;
	typedef struct _data5{  
		int vv[3][3];  }Data5;
	typedef struct _data{
		Data1 d1;
		Data2 d2;
		Data3 d3;
		Data4 d4;
		Data5 d5;
	}MyStruct; 
	
#pragma pack()
}

MyStruct.cpp

这里可以看到,我返回一个结构体指针,因为无法直接传递一个结构体。

extern "C"{
__declspec(dllexport) MyStruct* GetStruct();
__declspec(dllexport) void FreeStruct(MyStruct* ptr);//一定不要忘了释放内存函数
}//目的是暴露函数接口,也可以在头文件中声明
MyStruct* GetStruct() {  
    // 分配并初始化一个MyStruct实例的内存  
    MyStruct* pStruct = new MyStruct(); 
    //对pStruct指向结构体进行处理,下面是示例
    pStruct->d1.id[0] = 123;  
    pStruct->d1.id[1] = 23;  
    pStruct->d1.id[3] = 22;  

    pStruct->d2.aa = 456;  
    pStruct->d3.cc = 123.123;  
    pStruct->d5.vv[0][0] = 11;
    pStruct->d5.vv[1][1] = 12; 
    pStruct->d5.vv[2][1] = 13; 
    return pStruct;  
    }
    
void FreeStruct(MyStruct* ptr) {  
    delete ptr;  	
}

Class1.cs

在C#中构造一个跟C++一样的结构体

class Class1
    {


        public struct data1
        {
            public int[] id;
        }
        public struct data2
        {
            public int aa;
        }
        public struct data3
        {
            public float cc;
        }
        public struct data4
        {
            public int[] ee;
        }
        public struct data5
        {
            public int[,] vv;
        }
        public struct MyStruct
        {
            public data1 d1;
            public data2 d2;
            public data3 d3;
            public data4 d4;
            public data5 d5;


        }
        public static MyStruct my = new MyStruct();
    }

Class2.cs

由于MyStruct是复杂的嵌套结构体,因此创建一个MyStruct1用于接收传过来数据,不能直接传到MyStruct,接收数据会不对。

using System.Runtime.InteropServices;

namespace testdemo
{
    class Class2
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct MyStruct1
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public int[] id;
            public int aa;
            public float uu;
            public int[] ee;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] // 3x3总共9个元素,多加2是因为我发现传过来数据往后移了两位  
            public int[] dd;
            // 提供一个属性来方便按二维索引访问  
        }
        public static MyStruct1 my1 = new MyStruct1();
    }
}

Ctrl.cs

using System;
using System.Runtime.InteropServices;
namespace testdemo
{
    class Ctrl
    {
    	[DllImport("MyStruct.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern IntPtr GetStruct();
		[DllImport("MyStruct.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern void FreeStruct(IntPtr ptr);
        IntPtr ptr = GetStruct();
        if(ptr != IntPtr.Zero) // 确保地址有效  
        {
        	Class2.my1 = (Class2.MyStruct1)Marshal.PtrToStructure(ptr, typeof(Class2.MyStruct1));
        	ExData();//写一个my1数据复制给my的函数
            FreeStruct(ptr);//释放内存!!一定不要忘记!!
        }
     }
}

总结:

  1. 结构体从C++到C#,用结构体指针。
  2. 嵌套的复杂结构体传输,要在C#这边构造两个结构体,一个用于接收数据,一个用于还原结构体。
  3. 传输结束后,记得释放指针指向内存。

标签:struct,C#,MyStruct,C++,ptr,int,pStruct,public,结构
From: https://blog.csdn.net/qq_46028438/article/details/139353236

相关文章

  • 手机无线充电项目中CodeWorrior11.1安装时出现Cannot complete the install的解决方法
    项目场景:在使用NXP芯片开发手机无线充电项目的时候,安装CodeWorrior11.1软件和相关补丁过程中出现以下错误:Details提示:Cannotcompletetheinstallbecauseoneormorerequireditemscouldnotbefound.Softwarebeinginstalled:MCUv11.1DSCServicePackfor......
  • Vue 3 + TypeScript:构建强大前端应用的完美组合
    在前端开发的领域中,Vue3和TypeScript的结合正成为一种强大且流行的技术栈。今天,让我们深入探讨Vue3+TypeScript所带来的诸多优势和实践经验。一、Vue3的卓越特性Vue3引入了众多令人瞩目的新特性,如更好的性能、更灵活的组合式API等。这些特性使得我们能够以......
  • D. Invertible Bracket Sequences
    D.InvertibleBracketSequencesAregularbracketsequenceisabracketsequencethatcanbetransformedintoacorrectarithmeticexpressionbyinsertingcharacters'1'and'+'betweentheoriginalcharactersofthesequence.Forexam......
  • P10543 [THUPC2024] 黑白
    MyBlogsP10543[THUPC2024]黑白签到题。首先要判联通性。判完之后,统计全局的白格子个数\(s\)。因为删到最后,一定会留下一条白色路径,然后路径的长度在\(\bmod\;2\)意义下和\(n+m-1\)同余。而我们只关心能操作次数的奇偶性,所以只需要判断\(s-n-m\)的奇偶性即可。 int......
  • cadical基本数据结构分析3——运行状态控制
    在一对文件(options.hpp和options.cpp)运行控制参数统一初始化并设置动态增长规律; 1#ifndef_options_hpp_INCLUDED2#define_options_hpp_INCLUDED34/*------------------------------------------------------------------------*/56//Inorder......
  • SDC
    1、create_clockRef:https://blog.csdn.net/weixin_45791458/article/details/134217796create_clock[-nameclock_name][-add][source_objects][-periodperiod_value][-waveformedge_list][-commentcomment_string]//注:该命令的选项和参数顺序任意#假......
  • C++ vector 避免 fill 0
    我们在profiler的时候有的时候发现memset占用热点比较高。而且是std::vector::resize带来的。这个明显是没必要的,例如:std::vector<int>result;//这里resize会fill0result.resize(input_rows);for(inti=0;i<input_rows;++i){result[i]=transfer(input[i])......
  • Docker + maven build problem — unix://localhost:80: Permission denied
    使用docker-maven-plugin进行构建镜像报错如下:com.spotify.docker.client.shaded.org.apache.http.impl.execchain.RetryExecexecuteINFO:I/Oexception(java.io.IOException)caughtwhenprocessingrequestto{}->unix://localhost:80:Permissiondenied解决方案:Ad......
  • ZCMU-1149
    就是背包01问题#include<iostream>#include<cstring>/*01背包问题*/usingnamespacestd;constintmaxn=120;constintmaxm=1e5+10;intdp[maxm],a[maxm];intn,m;intmain(){intt;cin>>t;while(t--){cin>>n;......
  • ECShop电商商城wholesale_flow接口处存在SQL注入漏洞
    ECShop电商商城wholesale_flow接口处存在SQL注入漏洞FOFA语句app="ECSHOP"app="ECSHOP"&&icon_hash="-164358497"SQL注入漏洞POST/wholesale_flow.php?step=ajax_update_cartHTTP/1.1Host:User-Agent:Mozilla/5.0(WindowsNT10.0;Win64......