第一步:c++ 新建动态链接库,生成以下文件,cpp文件名是DLLTEST.cpp
在DLLTEST.cpp文件下 写一个简单函数,注意函数前_declspec(dllexport)
_declspec(dllexport) int add(int a, int b)
{
return a + b;
}
之后点击生成 在文件目录下生成dll文件
第二步:c# 下新建Form1 ,
在form1上放置一个按钮button,双击按钮写以下触发事件
private void button1_Click(object sender, EventArgs e){
int i=CPPDLL.add(10, 20);
MessageBox.Show(i.ToString());
}
第三步:查看被导出来DLL函数,我们使用vs自带的工具dumpbin。
在vs的安装文件中搜索”dumpbin.exe”,或者直接在我的电脑下搜索
双击运行
命令行:dumpbin –exports XXX.dll
运行结果如下图:
可以看出来,我们的add和subtract是被导出来了,但是函数名前后多出了很多字符,这是因为c++编译器为了支持重载,所以在编译的时候给每一个接口都重新定义了唯一的名字,这个过程被称为“名字粉碎”。这个名字就是dll找到接口的入口地址。
注意:EntryPoint后面跟着的是c++编辑器可以识别的函数入口,如果运行例子出现类似“……找不到程序入口”多半是没告诉编辑器能识别的接口名。
第四步:定义dll类,方便c#使用
public class CPPDLL{
[DllImport(@"DLLTEST.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "?add@@YAHHH@Z")]
public static extern int add(int x, int y);
}
第五步:c#点击生成exe,将之前的生成的动态链接库dll添加到刚才生成exe的文件夹下。点击运行,结果如图
附Form1.cs的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace FORM1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int i=CPPDLL.add(10, 20);
MessageBox.Show(i.ToString());
}
}
}
public class CPPDLL
{
[DllImport(@"DLLTEST.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "?add@@YAHHH@Z")]
public static extern int add(int x, int y);
}