C#调用C++dll文件的注意事项

一、基本概念

1、c++是非托管代码,c#是非托管代码,c#调用c++需要把c++编译成dll文件后才能用。

托管代码:由公共语言运行环境执行的代码。

非托管代码:在公共语言环境的外部,由操作系统直接运行的代码。

2、dll是动态库

静态库与动态库的区别

静态库:在程序的链接阶段被复制到了程序中,和程序运行时没有关系。

动态库:在链接阶段没有被复制到程序中,而是在程序在运行时由系统动态的加载到内存。

3、问题:c++工程中一个.cpp文件引用了一个dll文件,如何改为一个c#引用这个dll文件。

c++工程中有三个文件:

.h文件:声明函数的接口。

.dll文件:函数代码。

.lib:告诉连接器调用的函数在哪个dll文件中。

c#引用时只要把dll文件拷贝到c#工程的Debug 或Release文件夹下,再添加引用即可。

二、引用过程

1、c++ dll文件拷贝到c#工程的Debug 或Release文件夹下

2、c#工程下,项目——添加引用  将这个dll文件添加引用

3、c#工程下添加一个类,用来代替原来c++工程的.cpp主程序,同时在这个类中引用dll文件。

几种常用的声明方法:

(1)一般形式

c++:

void __stdcall SetOverallMarkCounts(int count);

c#:

 [DllImport("CSCInterface.dll", CallingConvention = CallingConvention.StdCall)] //dll文件名、c++ dll编码方式 
 public static extern void SetOverallMarkCounts(int count);//函数声明

注意:1)c++中使用的编码方式已经注明是__stdcall,故c#中使用  CallingConvention = CallingConvention.StdCall

(2)指针作为函数参数的形式

c++:

int __stdcall MarkCommand_Vector( int length, double* sitsetX, double* sitsetY);

c#:

[DllImport("CSCInterface.dll", CallingConvention = CallingConvention.StdCall)]  //矢量图命令分解
        public static extern int  MarkCommand_Vector(int length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] double[] sitsetX, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] double[] sitsetY);

定义一个相同类型的数组,并在数组前面加一个 [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]

(3)特殊形式

c++:

int __stdcall OpenUSB_Board(int deviceIndex,void *handle);

源码中需要给第二个参数传一个NULL,#define NULL    0

c#:

   [DllImport("CSCInterface.dll", EntryPoint = "OpenUSB_Board", CallingConvention = CallingConvention.StdCall)]  
        public static extern bool  OpenUSB_Board(int deviceIndex, IntPtr handle);

使用IntPtr类型

c#调用时

 flag = OpenUSB_Board(0, IntPtr.Zero );

猜你喜欢

转载自blog.csdn.net/kenjianqi1647/article/details/82838530