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;

这个方法的调用方法如下, 开辟内存和读取识别结果麻烦点:
 1 using System.Drawing;
 2 using System.Drawing.Imaging;
 3
 4 //开辟识别结果数组内存
 5 int nResultNum = 6; // 数值与代码无关
 6 var result = new Result();
 7 var rSize = Marshal.SizeOf(result);
 8 var resultsPtr = Marshal.AllocHGlobal(rSize * nResultNum);
 9
10 //获取图像数据指针
11 var image = new Bitmap("路径");
12 var bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
13
14 //识别图像
15 var r = PlateSDK.RecogImage(bmpData.Scan0, resultsPtr);
16
17 //读取识别结果
18 if(r != 0) return; // 识别失败, r为错误编号;
19 else
20 {
21   var results = new Result[nResultNum];
22   for(int i = 0; i < nResultNum; i++)
23     results[i] = (Result)Marshal.PtrToStructure(results + rSize * i, typeof(Result));
24 } // results 就是识别结果数组

嗯, 其中3/4是我遇到比较麻烦的, 需要熟悉 Marshal(msdn), IntPtr(msdn) 和 MarshalAs(msdn).

时间: 2024-11-08 17:59:46

C#对C++动态库的封装总结的相关文章

linux下把log4cxx封装成so动态库文件(一)

这是一个经常遇到的问题,在软件开发过程中,需要将某些功能封装成一个独立的模块,这样维护升级也很方便.现在我们就要把开源日志库log4cxx封装成so动态加载库文件. 在上一篇文章<log4cxx日志库RedHat下安装>中,我们已经将log4cxx安装在home/mac/log4cxx/log4cxx下了,那么接下来的操作我们就继续在这个路径下进行. 还是先tree一下/home/mac/log4cxx这个目录吧 log4cxx ---apr ---apr-util ---log4cxx 那再

将TCP 和UDP封装成动态库

my_socket.h #ifndef __MY_SOCKET_H__ #define __MY_SOCKET_H__ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #in

c++动态库封装及调用(1、动态库介绍)

1.一个程序从源文件编译生成可执行文件的步骤: 预编译 -->  编译 -->  汇编 --> 链接 (1)预编译,即预处理,主要处理在源代码文件中以"#"开始的预编译指令,如宏展开.处理条件编译指令.处理#include指令等. (2)编译过程就是把预处理完的文件进行一系列词法分析.语法分析.语义分析以及优化后生成相应的汇编代码文件. (3)汇编是将汇编代码转变成二进制文件. (4)链接将二进制文件链接成一个可执行的命令,主要是把分散的数据和代码收集并合成一个单一的

ios动态库

real framework中不可以使用类别 或 不可以不包含类文件 real framework 中直接调用NSClassFromString函数会返回null  需要强制加载指定类 或 直接通过类名引用 linux中静态库和动态库的区别 一.不同 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见

AppCan IDE3.3:支持插件动态库升级,节省70%测试时间

近日,AppCan IDE V3.3.0.JS SDK V1.0上线,新版本在开发速度上.效率上再次提升,同时将本地开发与云端协作更快速的连接,开发者将享受比快更快的流畅开发体验. 1.IDE 支持插件动态库升级,节省70%测试时间 本地打包支持iOS8+非越狱设备安装,测试插件只需打包一次,随时替换插件资源即可. 支持GIT代码托管,AppCan与"大众工场"打通 支持GIT代码托管,AppCan开发后台中的项目,可快速同步到大众工场中,实现协同化的项目开发管理. "Web

ios 开发中 动态库 与静态库的区别

使用静态库的好处 1,模块化,分工合作 2,避免少量改动经常导致大量的重复编译连接 3,也可以重用,注意不是共享使用 动态库使用有如下好处: 1使用动态库,可以将最终可执行文件体积缩小 2使用动态库,多个应用程序共享内存中得同一份库文件,节省资源 3使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的. 从1可以得出,将整个应用程序分模块,团队合作,进行分工,影响比较小. 等其他好处, 从2可以看出,其实动态库应该叫共享库,那么从这个意义上来说,苹果禁止iOS开

iOS 静态库,动态库与 Framework

iOS 静态库,动态库与 Framework 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件.另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间. 上面提到库在使用的时候需要

【转】分析Linux和windows动态库

原文地址:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系统的动态库由 于格式不同,在需要不同操作系统调用时需要进行动态库程序移植.本文分析和比较了两种操作系统动态库技术,并给出了将Visual C++编制的动态库移植到Lin

函数库:静态库和动态库

1.函数库 函数库其实就是一些写好的函数集合,方便别人的复用.实现的封装之后,最终的目的都是给别人调用. 2.库的形式 库的形式分:动态链接库和静态链接库. 优点: (1)库文件都是被编译好的二进制文件,别人看不到源代码,可以保持保密:(2)同时不会因为不小心被修改出现问题,便于维护. LINUX 下的库学习: 静态链接库:.a 文件 其实就是将多函数,做编译但是不链接生成的 .o 文件,使用 ar 工具打包为 .a 的文件.编译的阶段,当调用这些库的时候,链接器就会去 .a 的库文件中拿出被调