一、环境准备
电脑系统:Windows 10 专业版 20H2
IDE:Microsoft Visual Studio Professional 2022 (64 位) - Current 版本 17.11.4
其他:
二、测试目的
将基于C++创建DLL库,封装到C#生成的exe中。
一般C++创建的库,在C#中使用,都是采用DllImport导入的,且要求库处于exe相关路径下,
[DllImport("dddddd.dll", CallingConvention = CallingConvention.Cdecl)]
extern static int xxxxxx();
可是有时,就是只想要一个exe发出去,其他dll不想看到,咋办?
这里提供一种实现方式:将这类dll放入嵌入资源,一起打包成exe,点击exe时,将嵌入资源释放为dll文件,并存到临时文件夹中(也可放入内存中,但是实现好麻烦,少数几个接口,可以这样搞,如果数量太多,感觉也难搞),再通过SetDllDirectory指定dll路径。
三、创建非托管DLL
可以参考下,其他方式创建的dll,在C#上使用方法应该类似。
1、在VS中创建一个C++空项目
创建myFunc.h文件下添加
extern "C" _declspec(dllexport) int GetSum(int a, int b);创建myFunc.c文件下添加
int GetSum(int a,int b)
{return a + b;
}
2、修改项目属性
项目右键菜单 - 属性
①平台设置为x64
②配置属性-常规-配置类型,设为动态库.dll
③配置属性-C/C++-高级,编译为 C++代码
3、生成OK
4、添加一个版本资源文件
项目中的资源文件上右键菜单中:添加-资源-Version,生成xxxx.rc文件
打开此资源文件,设置版本后,为后续更新dll做准备。
添加完成资源文件后,仍需“重新生成”(做了任何改变,都要重新生成)。
四、创建C#工作台
1、创建C#工作台工程
先设置启动项目,然后按照 DllImport 的方式写好接口
2、复制非托管dll到特定位置
启动控制台前,需要先将C++非托管dll,复制到控制台下
3、生成失败
4、分析问题
一般这种检查以下方面
①检查接口格式是否ok
C# 内[DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl)]extern static int GetSum(int a, int b);
C++内extern "C" _declspec(dllexport) int GetSum(int a, int b);
②检查 工程为32位开始64位
5、生成ok
五、修改C#工作台工程
1、导入dll
将dll导入工程,并设置“生成操作”为“嵌入的资源”
2、添加代码
将资源文件内的dll释放到电脑临时文件区域,每次打开exe时,检查临时文件dll缺失情况以及版本问题。
string dllPath = Path.Combine(dllExpectedDirectory, "TestDll.dll");if (!File.Exists(dllPath)){using (Stream resource = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApp1.Resources.TestDll.dll")){using (FileStream file = new FileStream(dllPath, FileMode.Create)){resource.CopyTo(file);}}}// 在程序启动时调用SetDllDirectory(dllExpectedDirectory); //设置DLL期望路径
四、运行效果
五、工程资料下载
C# 将非托管Dll嵌入exe中(一种实现方法).rar: (访问密码: 1666)https://url48.ctfile.com/f/33868548-1463347567-b94e83?p=1666