您的位置:首页 > 编程语言 > C#

C++工程代码打包的dll在C#工程上使用注意点!变量对应关系与dll调用出错情况。

2017-05-16 16:08 676 查看
c++跟c#之间变量名对应关系参考博客:http://blog.csdn.net/huangxiangec/article/details/8616550
1、就是传入传出的数据变量之间的对应关系,否则很容易出错的。
例如自己在传入需读取图片数据路径时一直出错,都是坑,其实都是变量之间的转换关系出错了。
其C++的为char*变量,而C#在传给C++时应该对于string变量,其中C++与C#之间的string变量是不同一的。
具体的看下面的:

2、C#中int[]a的数组怎么赋值给C++函数中的形参int* aa 。

其方法为: [DllImport("CVdll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int ceshiInt(int[] number, int len);
//extern "C" __declspec(dllexport) int ceshiInt(int* number, int len);
int[] array = new int[] { 2, 1, 3 };
string path;
Show("1.jpg",5);
int jj;
jj = ceshiInt( array, 3);

3、C++中char*的如何传给C#的string。下面9会介绍如何把C#的string传给C++的char*(实际这两个类型是对应的),其中的方法是:
extern "C" Food_API char* Foodrecognition(int min_area); //其中的char*是函数返回值。

/*
C#调用dll的例子代码:
引用方法处代码为:
[DllImport("Foodrecognitiond.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool init();
[DllImport("Foodrecognitiond.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Foodrecognition(int min_area);

使用方法处代码:
init();
IntPtr name = Marshal.AllocHGlobal(1000);//分配一个内存空间
name=Foodrecognition(10000); //返回一个变量,这个变量代表着内存地址。其会在本地读取一张图片,为"1.jpg".
string strRoom = Marshal.PtrToStringAnsi(name); //把内存里的字符串提取出来。菜名之间使用逗号隔开,结尾使用\n结束。
*/截图如下:
  


 注意:每个接口函数都要进行进行dll文件引用,其中C#跟C++的变量对应关系跟变量是传入还是传出有关。
4、当C#调用的dll文件是x64平台文件时的主要点:
  C#平台要跟dll文件编译平台相同,当dll为x64时,则需要把“Any CPU”改为x64,因为其指的是x86平台。
如下:



改为:



这个过程需要注意:x64的配置是从Any CPU的配置上复制过来的。具体实现过程参考:
关于在VS上创建的工程从win32改为x64时导致断点无法生效的原因与解决方法! .

5、C#调用的dll文件时,其只需把对外接口函数添加如下代码即可:
extern "C" __declspec(dllexport)其它的函数不用添加。其中C#引用dll是不用h文件和lib文件。而C++调用dll文件时需要h文件的,否则会出现无法解析的函数定义。打包给C#使用的dll接口函数可以不用放到h文件声明,直接在cpp文件声明,但是为了通用性,一般把接口声明到h或hpp文件。
下面是打包给C#使用的:



6、调用函数的三种方法时间对比:C#调用dll;C++调用dll;C++调用源代码。
C#调用dll:



C++调用dll:



C++调用源代码:



 总结:看上面的好像C#的比较快,原因可能是那个计时器不准确导致的,实际上三种是差不多的。!
7、C#的引用带有预处理器定义的变量的dll需要的注意点:
编译时在预处理器上定义的变量在生成dll文件时都会被一起编译进dll文件,则在使用这个dll文件时不需要再在预处理器上定义变量。
8、C#调用dll时,其再运行的时候不会执行dll文件里的printf函数的。如果要输出的话要使用cout,其如下:



本来在dll文件里会打印一些目标的置信度的,但是其在C#工程里没有打印出来。要通过cout吧dll里的数据输出到C#对话框里。
9、C#的string变量与C++里的变量进行对应例子:



注意:还有就是那个text文本控件的文本如何转化为string。
10、使用C#调用dll是出现的错误:
    错误1:有时C#调用dll时,而且这个dll又关联其他dll时,如果缺失后进行调用或许不会报缺失某个dll,而是直接报最顶层的dll缺失模块。其结果大概如下:



        注意:只是缺少一个以来的caffe库就报找不到模块,并且不报其缺少drinkclassifierd.dll文件。

  错误2:主要是使用yolo工程时比较常见的错误,下面是两种不同模式编译的结果:



  


    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: