如何将C++ dll嵌入到wpf程序

最近在github上看到一个可以将窗口变成亚克力效果的win32项目。

这个项目是基于DX API的,所以理论来说效果更好。

目前网上应该有很多种将窗口变成亚克力效果的方法,并且可以直接使用C#实现。

但是我还是想把这个项目封装成dll并进行导出,给wpf使用。

项目地址:https://github.com/selastingeorge/Win32-Acrylic-Effect

 

DLL嵌入

我们知道在C#中调用C++ dll,需要将函数进行导出。并通过DllImport将函数进行导入。

DllImport内部的原理实际上也是LoadLibraryGetProcAddress

通过下面的链接可以了解到: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文件已经释放了。

posted @ 2025-06-06 16:52  zhaotianff  阅读(83)  评论(0)    收藏  举报