C#调用C++动态库方法及动态库封装总结
我只是粗浅的学习过一些C++语法, 变量类型等基础内容, 如有不对的地方还望指出. 如果你跟我一样, 对指针操作不了解, 对封装C++动态库头疼的话, 下面内容还是有帮助的.
转载请注明出处: http://www.cnblogs.com/zaiyuzhong/p/Csharp-package-Cplusplus-dll.html 首先给一个类型转换的表, 这个表可能跟使用时具体情况有关, 仅供参考, 点击这里查看. 1. C++变量类型大小写问题:
一种是小写的, 比如char. 这种是系统定义的(关键字); 另一种是CHAR, 这个是自定义的, 有说这个是宏, 有说这个在VC++里是.Net定义的, 具体怎样我还没遇到过, 没有例子供研究. C++是大小写敏感的. 2. int的长度问题:
int的长度和编译器是有关系的. 如果动态库和封装代码由同一个编译器编译运行时, 可以不考虑转换int长度.
3. 结构体成员的长度问题:
不好描述, 举个例子:
C++代码:
typedef struct Result
{
char color[8];
}
对应C#代码:
public struct Result
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] color;
}
//C#中public修饰符可根据需要修改为其他访问修饰符.
在调用前可先对数据长度进行验证后再调用.
4. 指针问题:
有两种情况, 一种是封装C++函数时, 参数有指针类型的, 如果该参数是引用类型, 那么在C#中使用该参数时传递的也是变量指针(引用), 所以不用处理; 如果该参数是结构类型, 如int* , 封装时需要表示为ref, 例如:
C++: int InitSDK(Config* pConfig); //Config是结构体;
C# : public int InitSDK(ref Config pConfig); //int类型是否修改参见上述问题2; 另外一种情况比较麻烦, C++函数需要给他分配一块内存空间:
C++: int RecogImage(const unsigned char* pbyBits, Result* pResult);
// pbyBits[in] 指向内存图像数据的指针,数据格式为输入图像的格式;
// pResult[out] 识别结果数组, 调用方开辟pResult[nResultNum]内存;(注: 这两行注释是文档上的函数说明)
Result是动态库定义的结构体, nResultNum是自己定义的变量, 数值与这里无关, 测试后发现声明参数类型为数组是不行的.
C#: [DllImport("dll路径")]
public static extern int RecogImage(IntPtr pbyBits, IntPtr pResult);
// 这里的IntPtr虽然也是结构体, 但由于它本身就代表一个指针所以不用ref; 这个方法的调用方法如下, 开辟内存和读取识别结果麻烦点:
using System.Drawing;
using System.Drawing.Imaging; //开辟识别结果数组内存
int nResultNum = ; // 数值与代码无关
var result = new Result();
var rSize = Marshal.SizeOf(result);
var resultsPtr = Marshal.AllocHGlobal(rSize * nResultNum); //获取图像数据指针
var image = new Bitmap("路径");
var bmpData = image.LockBits(new Rectangle(, , image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); //识别图像
var r = PlateSDK.RecogImage(bmpData.Scan0, resultsPtr); //读取识别结果
if(r != ) return; // 识别失败, r为错误编号;
else
{
var results = new Result[nResultNum];
for(int i = ; i < nResultNum; i++)
results[i] = (Result)Marshal.PtrToStructure(results + rSize * i, typeof(Result));
} // results 就是识别结果数组
嗯, 其中3/4是我遇到比较麻烦的, 需要熟悉 Marshal(msdn), IntPtr(msdn) 和 MarshalAs(msdn).
C#调用C++动态库方法及动态库封装总结的更多相关文章
- 三种dedecms调用相关文章的方法
在文章的末尾或侧边栏添加相关文章可以提高用户的黏度,提高pv,增加se的好印象(哈哈),那么dedecms如何调用相关文章呢?有三种方法可以实现. 第一种dedecms调用相关文章的方法,用默认的li ...
- Java调用动态库方法说明-最详细
Java不能直接调用由c或者c++写得dll(TF_ID.dll),所以只能采用jni得方法,一步一步生成符合规范得dll文件(假设叫FANGJIAN.dll),在FANGJIAN.dll这个文件里来 ...
- linux下java调用.so动态库方法2: JNA
摘自:http://blog.csdn.net/todorovchen/article/details/21319033 另请参见: http://blog.sina.com.cn/s/blog_8c ...
- 6.关于QT中的内存管理,动态的制作,动态库的调用,静态库的制作
一 QT的内存管理 1 QT中的内存管理是QObject来管理的 2 QT中的内存管理没有cocos2dx中的引用计数 3 组件能够指定父对象 QTimer *timer = QTime ...
- c++动态库封装及调用(3、windows下动态库调用)
1.DLL的隐式调用 隐式链接采用静态加载的方式,比较简单,需要.h..lib..dll三件套.新建“控制台应用程序”或“空项目”.配置如下: 项目->属性->配置属性->VC++ ...
- windows中静态库lib和动态dll的区别及使用方法
1. 静态库lib和动态dll的区别 1.1 项目类型 VS在建Win32项目时,有以下选项: windows应用程序控制台应用程序DLL静态库最后两个类型:DLL和静态库,这两种项目类型是不可以单独 ...
- 使用runtime给类动态添加方法并调用 - class_addMethod
上手开发 iOS 一段时间后,我发现并不能只着眼于完成需求,利用闲暇之余多研究其他的开发技巧,才能在有限时间内提升自己水平.当然,“其他开发技巧”这个命题对于任何一个开发领域都感觉不找边际,而对于我来 ...
- new关键字在虚方法的动态调用中的阻断作用
关于new关键字在虚方法动态调用中的阻断作用,也有了更明确的理论基础.在子类方法中,如果标记 new 关键字,则意味着隐藏基类实现,其实就是创建了与父类同名的另一个方法,在编译中这两个方法处于动态方法 ...
- Delphi - Windows系统下,Delphi调用API函数和7z.dll动态库,自动把文件压缩成.tar.gz格式的文件
项目背景 应欧美客户需求,需要将文件压缩成.tar.gz格式的文件,并上传给客户端SFTP服务器. 你懂的,7-Zip软件的显著特点是文件越大压缩比越高,在Linux系统上相当于我们Windows系统 ...
随机推荐
- synchronized使用说明
好久没有更新博客了,今天试着用简单的语言把synchronized的使用说清楚. synchronized是什么? synchronized是用来保证在多线程环境下代码同步执行的可重入的互斥锁.所谓互 ...
- 我的LaTeX中文文档模板
中文LaTeX处理模板 环境MiTex内核 编辑环境WinEdit 源码如下: \documentclass[a4paper,12pt]{article} \usepackage{CJK} %设定字号 ...
- phpstudy 局域网访问
安装mantis缺陷管理系统,我使用的是phpstudy集成环境.之前使用wamp,同事说phpstudy好更新php版本,所有就用phpstudy了. 今天安装好phpstudy,下载mantis安 ...
- 机器学习caffe环境搭建——redhat7.1和caffe的python接口编译
相信看这篇文章的都知道caffe是干嘛的了,无非就是深度学习.神经网络.计算机视觉.人工智能这些,这个我就不多介绍了,下面说说我的安装过程即遇到的问题,当然还有解决方法. 说下我的环境:1>虚拟 ...
- Ruby混合类型
当一个类拥有可以从多个父类继承的特点,类应该显示多重继承. Ruby没有直接支持多继承,但Ruby模块有另一个精彩使用.他们几乎消除多重继承的需要,提供了一个工厂,称为混入. 混合类型给一个精彩的控制 ...
- RakNet基本教程
官方网址:http://www.jenkinssoftware.com/raknet/manual/tutorialsample3.html Tutorial code sample 3 Remote ...
- Tomcat7.0+的JNDI问题
上次搭建spring+springmvc+mybatis框架时用的第三方连接池jar包,但是部署到tomcat中后访问没有问题,但是启动时报了个JNDI的错,我没用JNDI你给我报什么,fuck!把错 ...
- php五种常见的设计模式(转载)
很多人都想着写博客来记录编程生活中的点滴,我也不例外,但想了好长时间不知道写什么........万事开头难,先转载一篇吧..... 设计模式 一书将设计模式引入软件社区,该书的作者是 Erich Ga ...
- ModPagespeed for Apache安装配置
1.安装ModPagespeed #32位wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_i38 ...
- PHP预定义接口之 ArrayAccess
最近这段时间回家过年了,博客也没有更新,感觉少学习了好多东西,也错失了好多的学习机会,就像大家在春节抢红包时常说的一句话:一不留神错过了好几亿.废话少说,这篇博客给大家说说关于PHP预定义接口中常用到 ...