使用c#调用c++代码方法及原理(一)

在大型项目开发中,往往要使用强大的第三方库,比如说中间件使用基于c++开发的OpenDDS,但是项目逻辑层可能用的是其他语言,比如c#,所以基于这样的情况,不同编程语言之间的相互调动问题是逃避不了的。

举一个在windows平台,IDE在vs2015,c#调用c++的例子。

1、创建一个c++动态库项目

这个就不展开说了,网上的资料很多,不再叙述。

创建完成如图:

使用c#调用c++代码方法及原理(一)_第1张图片

2、生成基于c++的dll文件

应用程序如果想要访问某个DLL中的函数,那么该函数必须是已经被导出来的函数。

现在我们打开CSharpInvoke.cpp,添加如下代码:

_declspec(dllexport) int add (int a, int b)
{
      return a + b;
}

_declspec(dllexport) int subtract (int a, int b)
{
      return a - b;
}

为了让DLL导出函数,需要在每一个将要被导出的函数前面添加标识符:_declspec(dllexport)

编译生成文件,如图:

使用c#调用c++代码方法及原理(一)_第2张图片

那么如何查看该DLL的函数已经被导出来了呢?我们使用vs自带的工具dumpbin。

在vs的安装文件中搜索”dumpbin.exe”,并为之设置为系统环境变量,这样我们就可以在任何文件下使用dumpbin命令了。

运行如下图:
使用c#调用c++代码方法及原理(一)_第3张图片

可以看出来,我们的addsubtract是被导出来了,但是函数名前后多出了很多字符,这是因为c++编译器为了支持重载,所以在编译的时候给每一个接口都重新定义了唯一的名字,这个过程被称为“名字粉碎”。这个名字就是dll找到接口的入口地址。

4、c#应用程序调用dll

创建一个名叫start_cs的C#控制台程序。

填入如下代码:

    public class CPPDLL
    {
        [DllImport("use_c++.dll",EntryPoint = "?add@@YAHHH@Z")]
        public static extern int add(int x, int y);
        [DllImport("use_c++.dll", EntryPoint = "?subtract@@YAHHH@Z")]
        public static extern int subtract(int x, int y);
    }

    class Program
    {
        static void Main(string[] args)
        {
            int result = CPPDLL.add(10,20);
            Console.WriteLine("10 + 20 = {0}", result);

            Console.ReadLine();

        }
    }

注意:EntryPoint后面跟着的是c++编辑器可以识别的函数入口,如果运行例子出现类似“……找不到程序入口”多半是没告诉编辑器能识别的接口名。

运行:

使用c#调用c++代码方法及原理(一)_第4张图片

成功。

第一步简单的例子,我们是运行成功了的,而c++中存在的指针、或者我们需要调用c++对象中的一个接口,更深层次的关于调用问题,比如类型对照问题内存释放问题等后续会继续更新。

你可能感兴趣的:(.Net)