下面我们将在VS2017生成dll文件(动态库文件)和lib文件(静态库文件),这里以C语言为例,用最简单的例子,来让读者了解如何生成dll文件(动态库文件)

第一步:新建一个项目

VS2017生成DLL(C语言)文件并在C#中使用_#endif

第二步:选择Windows桌面向导(这里先不要去管上面的“动态链接库(DLL)”)

VS2017生成DLL(C语言)文件并在C#中使用_c语言_02

第三步:选择动态链接库,并空项目打勾√

VS2017生成DLL(C语言)文件并在C#中使用_标签名_03

 第四步:添加一个.c源文件

VS2017生成DLL(C语言)文件并在C#中使用_c++_04

第五步:(因为这里以C语言为例子,将后缀改为.c)

VS2017生成DLL(C语言)文件并在C#中使用_标签名_05

第六步:在c文件中输入一个简单的函数这里使用了_declspec(dllexport),但_declspec(dllexport)并不是必须的,后面一种方法将不使用_declspec(dllexport)




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

VS2017生成DLL(C语言)文件并在C#中使用_#endif_06

第七步:新建一个头文件

VS2017生成DLL(C语言)文件并在C#中使用_标签名_07

第八步:在头文件中输入函数的声明

VS2017生成DLL(C语言)文件并在C#中使用_#endif_08

这里也可以改成下面这样,extern "C" 如果是c语言调用并不需要,加这个是因为c++调用的话,指定c++调用方式和c语言一样. 加这个就是做兼容性的.




#ifndef SHARE_H
#define SHARE_H
#endif

#ifdef __cplusplus //(内置宏,如果是c++,在编译器预处理的时候加上extern,如果是c语言调用的时候是不处理的)
extern "C"
{
#endif


_declspec (dllexport) int sum(int a, int b);


#ifdef __cplusplus
}
#endif

第九步:编译

VS2017生成DLL(C语言)文件并在C#中使用_c++_09

第十步:Debug文件夹下的两个文件DLL.dll和DLL.lib就是我们要使用的两个文件了

VS2017生成DLL(C语言)文件并在C#中使用_html_10

因为使用的_declspec(dllexport),虽然这里我们只编译了一次,却生成了dll和lib两个文件

接下来在C# 中使用:首先将上面生成的dll放到C#的目录下,一般是\bin\x86\Debug,(注意下面将之前的DLL.dll改成了Project2.dll,非必须,保持一致就好)。




using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp12
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

//[DllImport("Project2.dll", CallingConvention = CallingConvention.Cdecl,EntryPoint = "sum")]
[DllImport("Project2.dll", EntryPoint = "sum")]
private static extern int sum(int a, int b);


private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(sum(10,20).ToString());
}
}
}

运行后:

VS2017生成DLL(C语言)文件并在C#中使用_html_11

托管调试助手 "PInvokeStackImbalance":“对 PInvoke 函数“WindowsFormsApp12!WindowsFormsApp12.Form1::sum”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。”


修改如下:(参考https://jingyan.baidu.com/article/d169e1860bb38f436611d8c8.html)



 [DllImport("Project2.dll", CallingConvention = CallingConvention.Cdecl,EntryPoint = "sum")]

运行正常:

VS2017生成DLL(C语言)文件并在C#中使用_html_12