Marshal在C#中的应用(void *指针到IntPtr的转化)
C#调用C语言的API时一般把void *指针转换成IntPtr,但这经常远远不够的。在C语言中void *是个万金油,尤其是一些老的c语言程序,所有的参数就一个void*指针,里面包罗万象,然后在程序中来一个switch,甚至多个switch来处理不同的参数。最近笔者就碰到了这个问题,不得不来研究一下怎么把void *指针转换成IntPtr。
1.void *指针到IntPtr的简单转化。
c语言函数原型:
int SetConfig(int type, void *p);
这里假设p的所传递的参数式是结构体A:
|
那么在C#中原型可以定义如下:
int SetConfig(int type, IntPtr p);
结构体A
|
注意这里的CharSet,它由c中wchar_t决定的,如果c程序编译时使用Unicode,这里就用CharSet.Unicode,否则使用CharSet.Ansi。关于字符串的编码问题如果不懂可以去网上查一下。至于怎么知道C语言是用Unicode还是Ansi编译,我是经过调用它的API测试出来的,调用成功了就说明他的编码和我的调用代码一致。
这里还有一个很重要的问题,那就是内存在编译时的分配问题。一般默认情况下,内存的分配是4byte的整数倍,在这里我省略了,但为了便于理解,补充一下。结构体A完整一点的定义:(注意Pack的值)
|
c语言是用的是非托管代码,c#使用的是托管代码,c#的调用代码如下:
A s_a = new A();int lenght = Marshal.SizeOf(s_a);IntPtr pA= Marshal.AllocHGlobal(lenght);Marshal.StructureToPtr(s_a, pA, true);int type = 1;int ret = SetConfig( type, pA);Marshal.FreeHGlobal(pA);
2.void *指针到IntPtr的复杂转化。
在这里结构体A变得复杂一点,如果它内部包含一个指向另一个结构体B的指针
struct A {wchar_t osdbuffer[100]; unsigned short ix; unsigned short iy;、B *pB; }; struct B {wchar_t title[20]; };
在C#中你要做的也就稍微复杂一点,也就是说你不但要为A分配内存,也要为B分配内存
B s_b = new B();//赋值省略int lenght1 = Marshal.SizeOf(s_b);IntPtr pB= Marshal.AllocHGlobal(lenght1);Marshal.StructureToPtr(s_b, pB, true);A s_a = new A();s_a.pB = pB;//其他赋值//int lenght2 = Marshal.SizeOf(s_a);IntPtr pA= Marshal.AllocHGlobal(lenght2);Marshal.StructureToPtr(s_a, pA, true);int type = 1; int ret = SetConfig( type, pA);Marshal.FreeHGlobal(pB);Marshal.FreeHGlobal(pA);
万变不离其宗,只要掌握了原理,不管void *指针传递的参数有多么复杂,都可以搞定。
Marshal在C#中的应用(void *指针到IntPtr的转化)相关推荐
- C++ void指针(void *)
void* 是一种特殊的指针类型,可用于存放任意对象的地址.一个 void* 指针存放着一个地址,这一点和其他指针类似. 在介绍 void 指针前,简单说一下 void 关键字使用规则: 如果函数没有 ...
- C++ void指针(void*)简介
void* 是一种特殊的指针类型,可用于存放任意对象的地址.一个 void* 指针存放着一个地址,这一点和其他指针类似. 在介绍 void 指针前,简单说一下 void 关键字使用规则: 如果函数没有 ...
- c++中的void指针和const指针
在c++中可以声明指向void类型的指针,指向void类型的指针称为void指针,此外,在声明指针时,还可以用关键字const进行修饰,用关键字const修饰的指针称为const指针. 1.void指 ...
- c语言中的void指针,C程序中void指针的概念
到目前为止,我对void指针的轻描淡写如下. 当使用关键字void声明指针变量时,它将成为通用指针变量.任何数据类型(char,int,float等)的任何变量的地址都可以分配给void指针变量. m ...
- C++中void和void*指针的含义 (指针类型的含义)
转载自:http://blog.csdn.net/lee_shuai 指针有两个属性:指向变量/对象的地址和长度,但是指针只存储地址,长度则取决于指针的类型:编译器根据指针的类型从指针指向的地址向后寻 ...
- c语言 万能函数指针,C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针...
什么是万能指针? 万能指针其实就是void *类型的指针,而void *指针一般被称为通用指针或叫泛指针.它是C语言关于纯粹地址的一种约定.当某个指针是void型指针时,所指向的对象不属于任何类型. ...
- 指针中NULL(空指针)和void指针
1:NULL指针 NULL指针一般用在初始化一个存储类型,这个NULL指针不能用于存放数据类型和访问(你用get()得不到一个具体值,但是对于一个指针变量,我们必须要将这个指针的指向说明,要么将这个指 ...
- C/C++语言void及void指针深层探索。C中void是什么意思? 为什么有时可用可不用?
C/C++语言void及void指针深层探索.C中void是什么意思? 为什么有时可用可不用? 1.概述 许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误. ...
- C++中的空指针和void * 指针
空指针(null pointer) 空指针不指向任何对象,在使用一个指针前首先要判断是否为空. 用法: int *ptr1=nullptr; //等价于int *ptr1=0; int *ptr2=0 ...
最新文章
- 2020年涨薪26-30%,能实现吗?18%数据科学家是这么期待的
- ICCV2017 | 一文详解GAN之父Ian Goodfellow 演讲《生成对抗网络的原理与应用》(附完整PPT)
- jetbrains 旗下所有工具 pycharm clion goland 配置导出及导入
- python 访问 zookeeper
- 数据库-优化-数据库系统配置优化-配置文件优化
- python返回unicode_我们如何从python中的字形id获取unicode?
- 数据库SQL语言从入门到精通--Part 4--SQL语言中的模式、基本表、视图
- itil 容量管理流程_探索ITIL和DevOps的边界
- [MM9]复制格式的快捷操作
- php处理ubb代码,过滤UBB代码的php类
- 网络请求 get 请求时, 如果参数中的字符带有+号
- python turtle画房子详细解释_Python turtle 绘图入门必知必会
- 回顾jvisualvm安装插件简单操作
- 【图像超分辨(SR)】通俗直观彻底理解双线性插值、双三次插值及其作用
- java 导出word 带图片
- 2021年清北等重点高校都有哪些冬令营?最全汇总看这里!
- 电脑点击我的计算机无法打开,双击我的电脑打不开怎么办
- 【Pytorch官方教程】从零开始自己搭建RNN1 - 字母级RNN的分类任务
- Saliency map (fixation map) 生成热点图-python实现
- TO B革命 读书笔记整理
热门文章
- 复旦大学计算机科学院夏令营,2020年复旦大学计算机科学技术学院夏令营接收推免生条件...
- html连在一起的选择器,请问关于css选择器的问题:两个类选择器连在一起是什么意思?...
- 节约里程法java代码_患者,男,70岁,有多年排尿困难,呈淋漓状,近2年来双侧腹股沟区出现半年圆形肿块,站立时明显,平卧后消失,体检时压迫内环肿块仍出现,诊断为...
- c++string替换指定位置字符_Lua 字符串
- 会自学的四足机器人,3.5个小时学会走路!
- JAVA子类是球父类是圆_java的父类和子类,这是矛盾...
- oracle 赋值到cmd,CMD操作oracle数据导库过程图解
- break后面的语句还执行吗_【自学C#】|| 笔记 5 条件语句if、switch
- 什么中文版软件可以操作mysql_一款软件,几乎可以操作~所有的~“数据库”,太牛逼了!...
- 牛客小白月赛12 F	华华开始学信息学 (分块+树状数组)