一、类型转化

下面重点罗列下常用的类型转化。

C++类型

C#类型

备注说明

Int

Int16、Int32

没有悬念,直接转化

Uint

UInt16、Uint32、int

在程序中,不太清楚是,就可以直接对应为int

Long

Int32

Long相对int就定型了,对应的就是Int32

DWORD(unsigned long)

Uint32

WORD(unsigned short)

Uint16

这是对WORD的认知。

Byte(Unsigned char)

Byte

DECIMAL

Decimal

位数转化

BOOL

bool

char

char

这种没有加指针,比较容易,直接对应入座

Handle(void *)

Intptr

函数中为窗口句柄,c#就是默认的为Intptr

HMODULE

Intptr

同上

HISTANCE

Intptr

同上

Int *、long *

Ref int、ref long

这种整形指针,在程序中是为了引用,所以在c#中对应的是ref,所以在关键词之前加入ref.

Int &.long &

Ref int 、ref long

解释同上,当然在关键词加入 out,也是可以的

Char *(LPSTR、Pchar)、const char *(LPCSTR)、

String

也是为了获取数据,在c#中string在应用中就是引用,所以直接改为string即可。Intptr也可以,不提倡。

Byte *

Ref byte、byte[]

程序byte * 是为了获取类型为byte数据,在C#则用byte数组获取存储数据。String也可以,但是不提倡,关键看看获取的数据,做什么用

GUID

Guid

Char[],byte[],in[]

可对应找指针类型对一个的转化

Char[],byte[],int,这种在c++中应用时,先初始化数组,然后定义一个指针指向数据地址,然后访问,所以在转化是,在对应为char*》string , int[]>int * > intptr

Char **,byte **

Intptr

这种双指针的调用,一般是访问二位数组,所以我们直接处理为Intptr,当然intptr和之前不一样,需要处理,可以看见例子说明。

结构体 * 变量名、结构体 &变量名。

Ref 结构体 变量名、intptr

在结构体引用,或者传入值c++一般是用指针,在c#中,用ref代替。当然intptr也可以,但是不太方便。

通常在只要你选择在win32运行环境中找到相匹配的CLR(公共语言运行库,负责资源管理:内存分配和回收,并保证应用和底层操作系统之间有必要分离)类型,就可应正常工作。当然也有例外:BOOL在c++中发现其实为int型,所以转化为int,而不是bool。

指针参数,在winAPI许多函数中将指针作为一个或者多个参数。指针的作用是存储数据的地址,而不是数据。指针的加入,增加了数据的复杂性,同时增加数据灵活性,实现数据的传入传出,如果只是值类型应用只能是传入数据。在应用中如果没有指针,您可以直接通过值在线程堆栈中传递数据。有了指针,可以通过引用传递数据,将数据的内存地址推入到线程堆栈中,然后函数通过内存地址间接访问数据。在c#用ref、out定义为类似指针作用关键词。out是ref一个参数规范,实际上他们在运行中产生相同的机器码,out作用为了让调用者明白,数据只是传出,ref表明数据传入也是获取。托管代码中ref、out参数另一个很好用的是,可以作为结构体、类、数组提供一个地址供调用。只有在发现ref或out参数不符合需要情况下,才会封装成更复杂的CLR类型。

在windows API中会有窗口句柄的获取或者赋值,其方法的传递是不透明的,如handle、void *、histance等。

少数情况下,API 函数也将不透明指针定义为 PVOID 或 LPVOID 类型。在 Windows API 的定义中,这些类型意思就是说该指针没有类型。当 一个不透明指针返回给您的应用程序(或者您的应用程序期望得到一个不透明指针)时,您应该将参数或返回值封送为 CLR 中的一种特殊类型 — System.IntPtr。当您使用 IntPtr 类型时,通常不使用 out 或 ref 参数,因为 IntPtr 意为直接持有指针。

在CLR类型系统中intptr是一种特殊的属性,没有固定的大小,在运行时再绑定,依据操作系统的正常指针而定。这意味着在 32 位的 Windows 中,IntPtr 变量的宽度是 32 位的,而在 64 位的 Windows 中,实时编译器编译的代码会将 IntPtr 值看作 64 位的值。当在托管代码和非托管代码之间封送不透明指针时,这种自动调节大小的特点十分有用。然而,当使用 Windows API 函数时,因为指针应是不透明的,所以除了存储和传递给外部方法外,不能将它们另做它用。这种“只限存储和传递”规则的两个特例是当您需要向外部方法传递 null 指针值和需要比较 IntPtr 值与 null 值的情况。为了做到这一点,您不能将零强制转换为 System.IntPtr,而应该在 IntPtr 类型上使用 Int32.Zero 静态公共字段,以便获得用于比较或赋值的 null 值。

封送文本,主要是指在获取数据时,数据可能是存储在char数组中,如果我们用string接收时,有可能为乱码。所以在函数调用过程中,当char *,char[]是作为输入数据时,可以改为string。当作为数据传出时,则要好好考虑了,有时需要改为char []。在c+程序中,就是在c中字符串实际上是只是一个字符值数组,通常为null,大多数windows API函数是按照对于ansi,将其作为字符值数组(比较常用),对于unicode,将其作为宽字符值数组。有时获取的数据为乱码时,可能就是需要转为unicode,就解决了。大多数windows API函数都带有LPTSTR或者LPCTSTR值。他们分别是可修改和不可修改的缓冲区,包含以null结束的字符数组。“C”代表const,意味数据不会传递到函数外部。“T”代表该参数可以是Unicode和ANSI,在CLR运行中取决你选择的字符集和底层操作系统的字符集.。所以函数声明时,加上DllImportAttribute 为CharSet.Auto就可以了。如果字符串参数只用作输入,则使用 System.String 类型。在托管代码中,字符串是不变的,适合用于不会被本机 API 函数更改的缓冲区。如 果字符串参数可以用作输入和/或输出,则使用 System.StringBuilder 类型。StringBuilder 类型是一个很有用的类库类型,它可以帮助您有效地构建字符串,也正好可以将缓冲区传递给本机函数,由本机函数为您填充字符串数据。一旦函数调用返回,您只 需要调用 StringBuilder 对象的 ToString 就可以得到一个 String 对象。

CharSet的各变量对char以及char[]的影响如下:
ANSI:char以及char[]占一个字节
AUTO:char以及char[]占两个字节
UNICODE:char以及char[]占两个字节

总体原则可以总结为:

1、在c++常用的基本类型(数值类型、字节类型)直接转化到c#中的数值类型。(原则是字节数,确定好)

2、在c++常用的指针类型(数值类型*、字节类型*)则转化为c#中的ref 数值类型、ref 字节类型。但是在常用时,针对char * ,转化为string。

3、在c++常用的构造类型(结构体、数组、枚举类型、共用体)行对比较复杂。枚举和共用体直接复制就可以用,结构体的声明随后重点讲,在函数调用时,如果为结构体 * 变量名,则为 ref 结构体 变量名。数组在 函数调用,可以直接写为数组名,也可以写为Intptr。

二、结构体

1、结构体的重定义。

在c++中会有很多结构体,结构体内有各种各样的数据类型,所以就牵涉到数据类型的转化,同时在通过结构体获取到数据后,也牵涉到编码转化问题。

结构体类型和类类型在语法上有很多相似之处,他们都是一种数据结构,都可以包括数据成员和方法成员。

结构体和类区别:

1、结构体是值类型,它在栈中分配空间;类是引用类型,他在堆中分配空间,栈存储的是引用。

2、结构体类型直接存储成员数据,类中数据类型存在堆中,然后通过在栈中引用,访问数据。因为结构体是值类型,直接存储,因此当对象的主要成员为数据切不大时,使用结构体效率更高。

3、结构体直接包含自己的数据,每个结构体都保存一份数据,在程序声明两个结构体对象,改变其中一个,另一个数据不变,但是类是引用,则另一个数据会改变。

4、结构体是值类型,不能初始化为null,复制时则数据全部复制。;类中的复制是引用的复制,数据较大时,结构体复制则效果不是很好。

结构和类的适用场合分析:

  1、当堆栈的空间很有限,且有大量的逻辑对象时,创建类要比创建结构好一些;

  2、对于点、矩形和颜色这样的轻量对象,假如要声明一个含有许多个颜色对象的数组,则CLR需要为每个对象分配内存,在这种情况下,使用结构的成本较低;

  3、在表现抽象和多级别的对象层次时,类是最好的选择,因为结构不支持继承。

  4、大多数情况下,目标类型只是含有一些数据,或者以数据为主。

结构体的声明、初始化、引用在c#还是很重要的,下面根据代码进行分析。

[cpp] view plaincopyprint?
  1. //C++的结构体
[cpp] view plaincopyprint?
  1. //录像索引列表文件
  2. typedef struct tagINDEX_INFO
  3. {
  4. DWORD dwStartTime;              //录像开始时间
  5. DWORD dwEndTime;                //录像停止时间
  6. BYTE  btFileType;                   //文件类型
  7. BYTE  btFileStatus;             //文件状态
  8. BYTE  Reserved[2];              //预留,LMC向NVR请求回放时Reserved[0]标识NVR发送速度,Reserved[1]存放录像倒放标志
  9. BYTE  btMAC[6];                 //设备MAC地址
  10. WORD  wChan;                    //设备通道
  11. DWORD dwIP1;                    //设备IP1
  12. DWORD dwIP2;                    //设备IP2,公网模式下,存储此文件所在的NVR的IP
  13. DWORD dwIP3;                    //设备IP3,V3061用来存储录像片段在录像文件的偏移量,勿动
  14. DWORD dwIP4;                    //设备IP4,V3061用来录像文件名,勿动
  15. DWORD dwFileOffset;             //文件偏移,用于文件下载时断点续传和定位
  16. DWORD dwReserved;               //预留,3070有用到,不要动它
  17. }INDEX_INFO, *LPINDEX_INFO;

C#结构体

[cpp] view plaincopyprint?

//录像索引列表文件
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,Pack = 1)]
        public struct NET_INDEX_INFO
        {
            public UInt32 dwStartTime; //录像开始时间
            public UInt32 dwEndTime; //录像停止时间
            public byte btFileType; //文件类型
            public byte btFileStatus; //文件状态
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public byte [] Reserved; //预留,LMC向NVR请求回放时Reserved[0]标识NVR发送速度,Reserved[1]存放录像倒放标志
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte [] btMAC; //设备MAC地址
            public UInt16 wChan; //设备通道
            public UInt32 dwIP1; //设备IP1
            public UInt32 dwIP2; //设备IP2,公网模式下,存储此文件所在的NVR的IP
            public UInt32 dwIP3; //设备IP3,V3061用来存储录像片段在录像文件的偏移量,勿动
            public UInt32 dwIP4; //设备IP4,V3061用来录像文件名,勿动
            public UInt32 dwFileOffset; //文件偏移,用于文件下载时断点续传和定位
            public UInt32 dwReserved; //预留,3070有用到,不要动它
        }

上面成员前面必须添加public,因为默认是private。

2、StructLayout特性

公共语言运行库利用StructLayoutAttribute控制类或结构的数据字段在托管内存中的物理布局,即类或结构需要按某种方式排列。如果要将类传递给需要指定布局的非托管代码,则显式控制类布局是重要的。它的构造函数中用 LayoutKind值初始化 StructLayoutAttribute 类的新实例。 LayoutKind.Sequential 用于强制将成员按其出现的顺序进行顺序布局。
System.Runtime.InteropServices.StructLayout   允许的值有StructLayout.Auto   StructLayout.Sequential   StructLayout.Explicit.  在应用中为了数据顺利传入,一般是用StructLayout.Sequential,意味着结构体体内数据传入的格局按照声明一样。 StructLayout.Explicit需要用FieldOffset()设置每个成员的位置这样就可以实现类似c的公用体的功能。
[StructLayout(LayoutKind.Explicit)] 
struct S1
{
  [FieldOffset(0)]
  int a;
  [FieldOffset(0)]
  int b;
}
这样a和b在内存中地址相同

StructLayout特性支持三种附加字段:CharSet、Pack、Size。     
·   CharSet定义在结构中的字符串成员在结构被传给DLL时的排列方式。可以是Unicode、Ansi或Auto。     
  默认为Auto,在WIN   NT/2000/XP中表示字符串按照Unicode字符串进行排列,在WIN   95/98/Me中则表示按照ANSI字符串进行排列。     
·   Pack定义了结构的封装大小。可以是1、2、4、8、16、32、64、128或特殊值0。特殊值0表示当前操作平台默认的压缩大小。

3.MarshalAs的使用

MarshalAs属性指示如何在托管代码和非托管代码之间封送数据。
[MarshalAs(UnmanagedType unmanagedType, 命名参数)]

常用的UnmanagedType枚举值:(详细内容查MSDN)

BStr   长度前缀为双字节的 Unicode 字符串;

LPStr  单字节、空终止的 ANSI 字符串。;

LPWStr  一个 2 字节、空终止的 Unicode 字符串;

ByValArray 用于在结构中出现的内联定长字符数组,应始终使用MarshalAsAttribute的SizeConst字段来指示数组的大小。常用的是数组对应的为ByAvlArray,string对应的是ByValStr。

转载于:https://www.cnblogs.com/qiri07/p/4871944.html

C# 与C++的数据转换相关推荐

  1. Python数据挖掘:数据转换-数据规范化

    来源:天善智能韦玮老师课堂笔记 作者:Dust ---------- 数据转换: 简单变换 1.数据变换的目的是降数据转化为更方便分析的数据. 2.简单变换通常使用函数变换的方式进行,常见的函数变换包 ...

  2. ggplot2:9绘图需要的数据整理技术-数据转换

    ggplot2绘图基础系列: - 1初识ggplot2绘制几何对象 - 2图层的使用-基础.加标签.注释 - 3工具箱-误差线.加权数.展示数据分布 - 4语法基础 - 5通过图层构建图像 - 6标度 ...

  3. 独家 | 数据转换:标准化vs 归一化(附代码链接)

    作者:Clare Liu, 英国金融科技数据科学家 翻译:林鹤冲 校对:王紫岳 本文约2300字,建议阅读10分钟 本文将解释数据转换中常见的特征缩放方法:"标准化"和" ...

  4. 数据仓库自动抽取:通过 SQL Server 企业管理器中的数据转换服务 (DTS) 设计器 创建 Analysis Services 处理任务...

    本次学习 是为了实现 通过 SQL Server 企业管理器中的 数据转换服务 (DTS) 设计器 创建 Analysis Services 处理任务 以实现数据仓库所需数据的自动抽取转换填充 --- ...

  5. python 文件格式转换_Python的处理数据,如何进行数据转换,学会三种方式

    平时我们在处理数据的时候,有些数据类型不是我们想要的,怎么办? 如: python数据转换 num01,num02是str类型,但是我们需要的是整型,所以通过int转换成了整数. 数据转换 如何完成数 ...

  6. Swift3.0语言教程字符串与URL的数据转换与自由转换

    Swift3.0语言教程字符串与URL的数据转换与自由转换 Swift3.0语言教程字符串与URL的数据转换 Swift3.0语言教程字符串与URL的数据转换与自由转换,字符串中的字符永久保存除了可以 ...

  7. Swift3.0语言教程字符串与文件的数据转换

    Swift3.0语言教程字符串与文件的数据转换 Swift3.0语言教程字符串与文件的数据转换,如果想要对字符串中的字符进行永久保存,可以将字符串中的字符写入到文件中.当然,开发者也可以将写入的内容进 ...

  8. 重零开始学前端-基础(2) 运算符和数据转换

    在上篇文章,我简单介绍了js中的数据类型,现在主要介绍js中的运算符合数据转换.运算符就是通过+.-.*./等方式来对数据变量进行更改或重新赋值的一个过程,在此期间代码结构非常简单,但是因为组合的方式 ...

  9. 数据绑定(十)Binding的数据转换

    原文:数据绑定(十)Binding的数据转换 当Source端Path所关联的数据与Target端目标属性数据类型不一致时,需要添加数据转换器,数据转换器是一个自定义的类,这个类需要实现IValueC ...

  10. 转载自csdn SQL SERVER 与ACCESS、EXCEL的数据转换

    代码 熟悉SQL SERVER 2000的数据库管理员都知道,其DTS可以进行数据的导入导出,其实,我们也可以使用Transact-SQL语句进行导入导出操作.在Transact-SQL语句中,我们主 ...

最新文章

  1. 论文翻译_论文翻译的注意事项有什么?
  2. Linux_文件系统磁盘分区
  3. liferay-ui:search-container 用法
  4. C# GC 垃圾回收机制原理
  5. (转)nmake学习笔记
  6. 新年到!充满年味的海报给你参考
  7. linux 下root 口令破解(二) ——说一下grub的密码和安全模式
  8. 安装Android SDK时,点击SDK Manager.exe闪退,并且jdk的环境变量是对的。
  9. modbus tcp主站和从站_实例讲解PLC实现modbus通讯
  10. Java调用网易163邮箱,发送邮件
  11. MOSEK Fusion Model
  12. 科比生涯数据分析——利用随机森林进行分类
  13. 面试必备:VUE面试题(含答案)
  14. c语言求圆锥的表面积和体积_c语言问题,输入圆锥的半径和高,得出表面积和体积。请问程序该如何改....
  15. c# .net对接企业微信小助手 接口请求时长预警
  16. MySQL字符集是什么
  17. oracle技术圈熊掌号,百度“熊掌号”低调上线,意味着什么?
  18. ios开发:UINavigationController反方向滑动push
  19. 模仿猫眼电影App一个动画效果
  20. 怎样将pdf压缩得很小?如何把pdf压缩到最小?怎么把pdf压缩到最小?如何把pdf文档压缩变小?怎么将pdf文档压缩至更小?怎么把pdf压缩到最小方法软件网站有哪些?

热门文章

  1. Flutter Scaffold组件详情配制使用
  2. 精通Android自定义View(十六)invalidate方法和requestLayout方法
  3. Java中httpClient中的设置超时时间
  4. Mr.J-- jQuery学习笔记(十九)--自定义动画实现图标特效
  5. Mr.J-- jQuery学习笔记(十六)--展开和收起动画折叠菜单的实现
  6. 错误的模糊应用(类继承问题)
  7. HTML+CSS(第二天)
  8. Hibernate学习之一级缓存
  9. PHP 查找链表倒数第i个节点
  10. [React] 尚硅谷 -- 学习笔记(五)