C#与C++互操作时的数据类型对应

news2024/11/30 10:33:20

C#和C++在互操作时,会涉及到数据类型对应的问题,如果数据类型用得不对,就会得不到想要的结果,严重的情况下,可能还会导致程序崩溃。这里做一下相关知识点的总结。

说明:

1. 表格第一列是Visual C++中的数据类型,第二列是标准C中的数据类型

2. 表格第三列括号中显示的是别名(关键字)。

3. 关于使用string还是StringBuilder,可以参考P/Invoke各种总结(三、与字符串交互char*,wchar_t*) - zhaotianff - 博客园

VC++Ansi CC#(CTS)说明
VOIDvoidSystem.Void(void)void类型,代表函数无返回值。在C++里函数无参数也可以传入void,在C#里不这么做。
HANDLEvoid *System.IntPtr or System.UIntPtr长度:32位(32位系统), 64位(64位系统)
BYTEunsigned charSystem.Byte(byte)长度:8位
SHORTshortSystem.Int16(short)长度:16位
WORDunsigned shortSystem.UInt16(ushort)长度:16 位
INTintSystem.Int32(int)长度:32 位
UINTunsigned intSystem.UInt32(uint)长度:32 位
LONGlongSystem.Int32(int)长度:32 位
BOOLlongSystem.Boolean(bool) or System.Int32(int)长度:32 位
DWORDunsigned longSystem.UInt32(uint)长度:32 位
ULONGunsigned longSystem.UInt32(uint)长度:32 位
CHARcharSystem.Char(char)字符集:ANSI(多字节)
WCHARwchar_tSystem.Char(char)字符集:Unicode(宽字符)
LPSTRchar *System.String(string) or System.Text.StringBuilder字符集:ANSI(多字节)
LPCSTRconst char *System.String(string) or System.Text.StringBuilder字符集:ANSI(多字节)
LPWSTRwchar_t *System.String(string) or System.Text.StringBuilder字符集:Unicode(宽字符)
LPCWSTRconst wchar_t *System.String(string) or System.Text.StringBuilder字符集:Unicode(宽字符)
FLOATfloatSystem.Single(float)长度:32 位
DOUBLEdoubleSystem.Double(double)长度:64 位

4. 如果启用了“允许不安全代码”,可以使用指针类型来代替System.IntPtr or System.UIntPtr

一般情况下,推荐使用System.IntPtr or System.UIntPtr类,但是如果需要进行指针偏移,就一定要用指针类型,而不是System.IntPtr or System.UIntPtr。

下面的示例代码将会说明第4点。

一、使用IntPtr的情况

使用C++创建共享内存并写入数据(示例代码,仅供参考)

 1     RECT rect{ 100,100,100,100 };
 2     auto len = sizeof(rect);
 3 
 4     HANDLE m_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, MemorySize, "HelloWorld");
 5     if (m_handle != NULL)
 6     {
 7         PVOID m_pView = MapViewOfFile(m_handle, FILE_MAP_ALL_ACCESS, 0, 0, MemorySize);
 8         if (m_pView != NULL)
 9         {
10             memcpy_s(m_pView, MemorySize, (void *)&rect, len);        
11 
12             //程序退出时的资源释放操作
13             //.......
14         }
15     }

使用C#读出

 1             IntPtr withoutOffsetPtr = OpenFileMapping(FILE_MAP_READ, false, "HelloWorld");
 2             IntPtr mapView = MapViewOfFile(withoutOffsetPtr, FILE_MAP_READ, 0, 0, MemorySize);
 3             Rect rect = new Rect();
 4             var size = Marshal.SizeOf(rect);
 5             IntPtr ptr = Marshal.AllocHGlobal(size);       //往IntPtr里拷贝数据需要提前分配空间,否则会报错
 6             byte[] buffer = new byte[size];
 7             Marshal.Copy(mapView, buffer, 0, size);        //先拷贝到字节数组
 8             Marshal.Copy(buffer, 0, ptr, size);            //再拷贝到IntPtr
 9             var obj = Marshal.PtrToStructure(ptr, typeof(Rect));  //将IntPtr转换成结构体
10             rect = (Rect)obj;
11 
12             Console.WriteLine($"Rect:left={rect.left},top={rect.top},right={rect.right},bottom={rect.bottom}");

复制代码

二、使用指针的情况

使用C++创建共享内存并写入数据

复制代码

 1     RECT rect{ 10,10,10,10 };
 2     POINT point{ 3,3 };
 3     auto len = sizeof(rect);
 4 
 5     HANDLE m_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, MemorySize, "HelloWorld2");
 6     if (m_handle != NULL)
 7     {
 8         PVOID m_pView = MapViewOfFile(m_handle, FILE_MAP_ALL_ACCESS, 0, 0, MemorySize);
 9         if (m_pView != NULL)
10         {
11             //先写入rect
12             memcpy_s(m_pView, MemorySize,(void *)&rect, len);
13 
14             char* p = (char *)m_pView;
15             p = p + len;
16             m_pView = (void *)p;
17 
18             //再写入Point
19             memcpy_s(m_pView, MemorySize,(void *)&point, sizeof(point));
20             
21             //程序退出时的资源释放操作
22             //.......
23         }
24     }

使用C#读出(由于在写入Point数据时,指针的位置已经不是当初映射出来的起点了,要偏移,就需要使用指针)

 1             //这一部分操作跟上面函数是一样的
 2             IntPtr withoutOffsetPtr = OpenFileMapping(FILE_MAP_READ, false, "HelloWorld2");
 3             IntPtr mapView = MapViewOfFile(withoutOffsetPtr, FILE_MAP_READ, 0, 0, MemorySize);
 4             Rect rect = new Rect();
 5             var size = Marshal.SizeOf(rect);
 6             IntPtr ptr = Marshal.AllocHGlobal(size);
 7             byte[] buffer = new byte[size];
 8             Marshal.Copy(mapView, buffer, 0, size);
 9             Marshal.Copy(buffer, 0, ptr, size);
10             var obj = Marshal.PtrToStructure(ptr, typeof(Rect));
11             rect = (Rect)obj;
12 
13             Console.WriteLine($"Rect:left={rect.left},top={rect.top},right={rect.right},bottom={rect.bottom}");
14 
15             //使用指针
16             unsafe
17             {
18                 byte* b = (byte*)mapView;
19                 b += size;
20                 mapView = (IntPtr)b;
21             }
22 
23             //读取Point结构的值
24             Point point = new Point();
25             size = Marshal.SizeOf(point);
26             ptr = Marshal.AllocHGlobal(size);
27             buffer = new byte[size];
28             Marshal.Copy(mapView, buffer, 0, size);
29             Marshal.Copy(buffer, 0, ptr, size);
30             obj = Marshal.PtrToStructure(ptr, typeof(Point));
31             point = (Point)obj;
32 
33             Console.WriteLine($"Point:x={point.x},y={point.y}");

 示例代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2225924.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Docker大揭秘】

Docker 调试一天的血与泪的教训:设备条件:对应的build preparation相应的报错以及修改 作为记录 构建FASTLIO2启动docker获取镜像列出镜像运行containerdocker中实现宿主机与container中的文件互传 调试一天的血与泪的教训: 在DOCKER中跑通F…

numpy——数学运算

一、标量——矢量 import numpy as npa 3.14 b np.array([[9, 5], [2, 7]])print(a) print(b)# ---------- 四则运算 ---------- print(a b) # np.add print(a - b) # np.subtract print(a * b) # np.multiply print(a / b) # np.divide 二、矢量——矢量 import nump…

Claude Financial Data Analyst:基于Claude的金融数据分析工具!免费开源!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…

MPC模型预测控制与RL强化学习的差异性

模型预测控制(Model Predict Control,MPC) 模型预测控制与强化学习的差异性调研 概述 MPC 是一种使用数学模型在有限时间内实时优化控制系统的技术,自二十世纪六七十年代问世以来,已广泛应用于化学工程、炼油、先进…

Java:String类(超详解!)

一.常用方法 🥏1.字符串构造 字符串构造有三种方法: 📌注意: 1. String是引用类型,内部并不存储字符串本身 如果String是一个引用那么s1和s3应该指向同一个内容,s1和s2是相等的,应该输出两…

《深度学习》模型的部署、web框架 服务端及客户端案例

目录 一、模型的部署 1、模型部署的定义与目的 1)定义 2)目的 2、模型部署的步骤 1)导出模型 2) 部署模型 3)测试模型 4)监控模型 3、模型部署的方式 1)云端部署 2)嵌入…

autMan奥特曼机器人-对接Docker版本NTQQ详细教程

准备 1、准备一台服务器,amd64/arm64都可以,配置最好还是2核保底吧。 2、准备一个VNC软件。1Remote:点此下载 3、准备手机登陆机器人QQ号,扫码 NTQQ相关 NTQQ一键脚本(适用于小白支持autMan/无界) 复制以…

linux标准 I/O

FILE 指针标准输入、标准输出和标准错误检查或复位状态I/O 缓冲控制文件 I/O 内核缓冲的标志直接 I/O:绕过内核缓冲stdio 缓冲 FILE 指针 FILE 是一个结构体数据类型,它包含了标准 I/O 库函数为管理文件所需要的所有信息,包括用于实际I/O 的…

基于Spring Boot的宿舍管理系统设计与实现(源码+定制+开发)宿舍信息管理平台、智能宿舍系统开发、学生宿舍管理平台设计、宿舍入住与信息管理

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

单节点kubernetes-1.20二进制部署

文章目录 一, 集群拓扑二,架构图三,前置准备1.环境准备1.1操作系统初始化配置(1)关闭防火墙(2)关闭selinux(3)关闭swap(4)根据规划设置主机名(5&a…

[简易版] 自动化脚本

前言 uniapp cli项目中没办法自动化打开微信开发者工具,需要手动打开比较繁琐,故此自动化脚本就诞生啦~ 实现 const spawn require("cross-spawn"); const chalk require("picocolors"); const dayjs require("dayjs&quo…

实战教程:利用Docker容器化技术部署Szurubooru图像分享平台

实战教程:利用Docker容器化技术部署Szurubooru图像分享平台 一、Szurubooru介绍1.1 Szurubooru简介1.2 主要特点1.3 主要使用场景 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker comp…

numpy——索引切片

一、索引和切片 import numpy as npx np.arange(48).reshape(6, 8) print(x)# 选取第二行 print(x[1]) #从0开始,取得第2行# 选取第二行, 第二列 print(x[1][1])# 选取第三行到最后一行, 第一列到最后一列 print(x[2:,2:])# 花式索引 (1, 1) 和 (4, 4) print(&quo…

MPP音视频总结

基础篇 1.常用图像格式介绍 常用图像像素格式 RGB 和 YUV。 1.1RGB RGB分类通常指的是将图像或颜色按照RGB(红、绿、蓝)颜色空间进行分组或分类。RGB图像格式通常包括RGB24(RGB888)、RGB32、RGBA、RGB565等。 RGB24是一种常用…

【CSS】入门详解

你是否曾经浏览网页时,被一些网站精美的布局、炫酷的动画和赏心悦目的色彩所吸引?这背后神奇的力量就是 CSS(层叠样式表)。CSS 就像网页的化妆师,它负责网页的样式和布局,让原本枯燥的 HTML 结构变得生动有…

AttributeError: module ‘pandas‘ has no attribute ‘datetime‘

今天在进行时间序列问题处理时候,发生如下报错: AttributeError: module pandas has no attribute datetime 因为在新的pands版本中pandas已不再支持datetime模块。 from datetime import datetime 需要导入datetime库。 原代码: impor…

2025选题|基于Hadoop的物品租赁系统的设计与实现

作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,…

《虚拟现实的边界:探索虚拟世界的未来可能》

内容概要 在虚拟现实(VR)技术的浪潮中,我们见证了其从实验室的奇想逐渐走向日常生活的非凡旅程。技术发展的背后是不断突破的创新,早期的设备虽然笨重,但如今却趋向精致、轻巧,用户体验显著提升。想象一下…

【MySQL】视图特性 用户管理

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:了解什么是视图,我们又该如何管理用户。 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! >…

旧衣物回收小程序开发,线上线下相结合

当下,绿色发展是重中之重,旧衣回收作为一件利国利民的模式,在发展中深受大众欢迎。随着大众生活水平的提高,家中闲置的衣物逐年增加,这也为旧衣回收市场发展提供了广阔的发展前景,为入局者和创业者提供新的…