说明
前段时间做了嵌入式系统大作业,其中由于我们的workstation端采用的是c++语言编写的,而winform的gui界面是以c语言的形式编写的,因此我们要将workstation里的函数以c语言的形式封装成dll,进而可以在winform中调用。
关于Dll
Dll又分为托管的和非托管的,首先解释一下,托管DLL和非托管DLL的区别。狭义解释讲,托管DLL就在Dotnet环境生成的DLL文件。非托管DLL不是在Dotnet环境生成的DLL文件。
托管DLL文件,可以在Dotnet环境通过用“添加引用”的方式,直接把托管DLL文件添加到项目中。然后通过 Using DLL命名空间,来调用相应的DLL对象。
非托管DLL文件,在Dotnet环境应用时,通过DllImport调用。
很明显,在我们做的项目中,用的是非托管的dll,因此这里主要讲解非托管Dll的生成和引用。
步骤
1、首先创建一个c++空项目
命名随意,示例中命名为dlltest
2、添加头文件和源文件
头文件里首先添加一个类,命名随意,这里依旧命名dlltest
注意若想要以c语言封装,图中标记的一定要存在。
源文件cpp中写入要封装的函数(注意函数名称首字母最好大写),这里举例经典示例
第一行中头函数的引用就是之前添加的头文件的名字
3、封装
项目—>属性—>配置属性—>常规—>配置类型—>改成动态库(.dll)
项目—>属性—>配置属性—>C/C++—>高级—>编译为—>改成C++
点击确定后将其生成
4、引用
我们另行创建一个c#项目,这里用控制台应用,命名为dlltest2
我们在dlltest文件里生成的debug中找到.dll文件,将其复制到生成的dlltest2文件中的bin—>debug里
添加图中第6行和第12、13行程序,其中12行引号中的是dll的名称,13行中的int Sum(int a,int b)是函数的名称和返回值
然后就可以用这个函数啦
代码
dlltest.h:
#pragma once
extern "C" _declspec(dllexport) int Sum(int a, int b);
class dlltest
{
public:
};
dlltest.cpp:
#include "dlltest.h"
#include "iostream"
using namespace std;
int Sum(int a, int b)
{
return a + b;
}
dlltest2:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace dlltest2
{
class Program
{
[DllImport("dlltest.dll", CallingConvention = CallingConvention.Cdecl)]
extern static int Sum(int a, int b);
static void Main(string[] args)
{
Console.WriteLine(Sum(2, 3));
Console.ReadLine();
}
}
}
若存在多个函数需要封装成Dll
整体步骤类似,只是代码部分略有改动
代码
头文件:
#pragma once
extern "C" {
//_declspec (dllexport)加上所封装的函数1名称
_declspec (dllexport) int Sum();
//_declspec (dllexport)加上所封装的函数2名称
_declspec (dllexport) void Close();
//可以继续添加
}
class dlltest
{
public:
};
源文件:
注意没有主函数,所有函数名称首字母大写即可。
调用:
每个函数都添加如下程序即可
class Program
{
[DllImport("dlltest.dll", CallingConvention = CallingConvention.Cdecl)]
extern static int Sum();
[DllImport("dlltest.dll", CallingConvention = CallingConvention.Cdecl)]
extern static void Close();
……
}
欢迎批评和指正