首页 技术 正文
技术 2022年11月13日
0 收藏 445 点赞 4,767 浏览 1926 个字
  我只是粗浅的学习过一些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).

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,965
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,486
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,331
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,114
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,747
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,781