c#与c++与互操作实例讲解

  

一、c#调用c++库

  

1,创建c++库

  

打开VisualStudio,创建一个c++工程,输入项目名称HelloWorldLib

  

 c#与c++与互操作实例讲解

  

确定,然后下一步。选择应用程序类型为DLL

  

 c#与c++与互操作实例讲解

  

单击完成,我们就创建好了一个c++库的项目。

  

这里为了方便,我们直接在HelloWorldLib.cpp里定义函数

  

c++库导出有两种方式

  

一,以C语言接口的方式导出

  

这种方法就是在函数前面加上,外面的“C”使用__declspec (dllexport)

  

加上外来的“C”后,会指示编译器这部分代码按C语言的进行编译,而不是c++的。

        # include“stdafx.h”   # include      外来的“C”使用__declspec (dllexport)无效HelloWorld (char *名称);         外来的“C”使用__declspec (dllexport)无效HelloWorld (char *名称)   {   std:: cout & lt; & lt;“Hello World”& lt; & lt;名字& lt; & lt;std:: endl;   }      

,

  

二,以模块定义文件的方式导出

  

在工程上右键,选择添加-》新建项

  

 c#与c++与互操作实例讲解

  

然后选择代码——》模块定义文件

  

 c#与c++与互操作实例讲解

  

在Source.def中输入

        图书馆      出口   HelloWorld      

,

  

出口下面就是要导出的函数,这里不需要添加分号隔开,直接换行就行。

  

此时,我们函数的定义如下

        # include“stdafx.h”   # include      空白HelloWorld (char *名称);         空白HelloWorld (char *名称)   {   std:: cout & lt; & lt;“Hello World”& lt; & lt;名字& lt; & lt;std:: endl;   }      

,

  

编译,生成dll。这里需要注意的是,如果生成是64位的库,c#程序也要是64位的,否则会报错。

  

2,使用c#调用

  

接下来我们新建一个c#控制台项目

  

 c#与c++与互操作实例讲解

  

打开前面c++库生成的目录,将HelloWorldLib.dll复制到c#工程的调试目录下。也可以不复制,只需在引用dll的时候写上完整路径就行了。这里我是直接复制到调试目录下

        使用System.Runtime.InteropServices;      名称空间ConsoleApplication2   {   类项目   {   [DllImport (“HelloWorldLib.dll”)]   公共静态走读生空白HelloWorld(字符串名称);//可以通过入口点特性指定函数入口,然后为函数定义别名      [DllImport (“HelloWorldLib。dll”,入口点=癏elloWorld”))   公共静态走读生空白CustomName(字符串名称);   静态void Main (string [] args)   {   HelloWorld(“莉莉”);//跟上面是一样的   CustomName(“奇奇”);   }   }   }      

,

  

运行程序,结果如下:

  

 c#与c++与互操作实例讲解

  

这样就成功创建了一个c#可以调用的c++库

  

下面我们动态调用c++库,这里委托的作用就比较明显了。把委托比喻为c++的函数指针,一点也不为过。

  

我们在c++库中再新增一个函数GetYear(),用来获取当前年份。

        int GetYear ();      int GetYear ()   {   SYSTEMTIME tm;   GetLocalTime(及tm);      返回tm.wYear;   }      

,

  

记得在导出文件中(Source.def)增加GetYear。编译,生成新的DLL

  

再新建一个c#控制台程序

  

代码如下:

        使用系统;   使用System.Runtime.InteropServices;      名称空间ConsoleApplication3   {      类项目   {   [DllImport (“kernel32.dll”)]   公共静态走读生IntPtr LoadLibrary (string lpFileName);      [DllImport (“kernel32.dll”)]   公共静态走读生IntPtr GetProcAddress (IntPtr hModule,字符串lpProcName);      [DllImport (“kernel32”,入口点=癋reeLibrary”, SetLastError=true))   公共静态走读生bool FreeLibrary (IntPtr hModule);//声明委托,这里的签的名,需要跟c++库中的对应   委托int GetYearDelegate ();      静态void Main (string [] args)   {   GetYearDelegate m_fGetYear;   IntPtr hModule=LoadLibrary (“HelloWorldLib.dll”);   如果(hModule !=IntPtr.Zero)   {   IntPtr hProc=GetProcAddress (hModule GetYear);   如果(hProc !=IntPtr.Zero)   {   m_fGetYear=(GetYearDelegate)元帅。GetDelegateForFunctionPointer (hProc typeof (GetYearDelegate));//在这里可以调用   int年=m_fGetYear ();   控制台。WriteLine(“年份是:" +);   }   }   }   }   }

c#与c++与互操作实例讲解