如何将C++ dll嵌入到wpf程序
最近在github上看到一个可以将窗口变成亚克力效果的win32项目。
这个项目是基于DX API的,所以理论来说效果更好。
目前网上应该有很多种将窗口变成亚克力效果的方法,并且可以直接使用C#实现。
但是我还是想把这个项目封装成dll并进行导出,给wpf使用。
项目地址:https://github.com/selastingeorge/Win32-Acrylic-Effect
DLL嵌入
我们知道在C#中调用C++ dll,需要将函数进行导出。并通过DllImport将函数进行导入。
DllImport内部的原理实际上也是LoadLibrary和GetProcAddress。
通过下面的链接可以了解到:https://stackoverflow.com/a/14471704/10861316
LoadLibrary是一种动态加载技术,也就是运行时才需要这个dll。
所以我们可以将dll进入嵌入 ,等到C#程序初始化时,将dll释放出来,就可以保证程序正常运行。
实现步骤
1、创建一个C++动态链接库项目

创建一个导出函数
source.h
1 #pragma once 2 3 extern "C" __declspec(dllexport) int Add(int a, int b);
source.cpp
1 #include "source.h" 2 3 int Add(int a, int b) 4 { 5 return a + b; 6 }
2、将生成的DLL复制到C#工程中
这里我们可以直接添加到资源中,也可以将文件的生成操作改为“嵌入的资源”
这里我们以嵌入的资源为例

3、在程序初始化时释放DLL文件
1 private const string DllName = "Project1.dll"; 2 3 public MainWindow() 4 { 5 InitializeComponent(); 6 7 ExtractDll(DllName); 8 } 9 10 private static void ExtractDll(string dllName) 11 { 12 var assembly = Assembly.GetExecutingAssembly(); 13 var resourceName = Array.Find( 14 assembly.GetManifestResourceNames(), 15 name => name.EndsWith(dllName, StringComparison.OrdinalIgnoreCase) 16 ); 17 18 if (resourceName == null) 19 throw new Exception($"Resource {dllName} not found in assembly."); 20 21 var extractedPath = Environment.CurrentDirectory + "\\" + dllName; 22 23 using (var stream = assembly.GetManifestResourceStream(resourceName)) 24 using (var file = new FileStream(extractedPath, FileMode.Create, FileAccess.Write)) 25 { 26 stream.CopyTo(file); 27 } 28 }
4、引入P/Invoke签名
1 [DllImport("Project1.dll")] 2 public static extern int Add(int a, int b);
后续就是正常调用即可。
要注意的是,在调用前,一定要保证DLL文件已经释放了。

浙公网安备 33010602011771号