最近一直在做的Ayase项目 (获取UI) 性能不太行,于是就开始思考用C++。其实纯C++我是尝试过的,但是一点 WinForm / MFC / C++ 的底子都没有,头大得很。于是乎开始想要使用 C++ 完成这部分工作,然后再使用C# 做 UI 等其他内容。
解决方案
主要思路:
C++的项目编译成.dll(动态链接库dynamic link library)C#的项目通过P/Invoke调用C++暴露出来的接口
动手
- Step 1: 为解决方案添加新项目
- Step 2: 为新项目添加
.h,.cpp文件
.h 模板:
#pragma once
#ifdef GIUIAUTOMATIONMANAGER_EXPORTS
#define GIUIAUTOMATIONMANAGER_API __declspec(dllexport)
#else
#define GIUIAUTOMATIONMANAGER_API __declspec(dllimport)
#endif
extern "C" GIUIAUTOMATIONMANAGER_API int InitializeUIAutomation();
extern "C" GIUIAUTOMATIONMANAGER_API wchar_t* GetForeGroundWindowName();
解释:
- 文件名为:
GIUIAutomationManager - 定义的一些宏主要是在
import / export方面起作用,大家可以照葫芦画瓢,不用太担心 int InitializeUIAutomation(),wchar_t* GetForeGroundWindowName()是申明的可供外界调用的函数
.cpp 模板:
#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
#include "GIUIAutomationManager.h" // 前面的头文件
...
这里大家基本上也都能理解了。
- Step 3: 配置
.dll的生成路径 和.NET项目的生成路径
其实大家怎么配都行,之后最后 DLLImport的时候的 .exe 和 .dll 的相对路径关系对就没问题,下面是推荐。
建议都按照上面这个来:
$(SolutionDir)$(Platform)\$(Configuration)\
在.NET项目中,输出路径粘贴上面这个会自动进行转换,无需担心:
- Step 4: 编译
.dll: 对C++项目右键生成。
- Step 5:
P/Invoke调用。
由于.NET项目会生成在类似于下面这个地方:
所以.dll相对于.exe的目录为: ../<xxx>.dll
下面是范例:
[DllImport("../Ayase.Accessibility.dll")]
public static extern int InitializeUIAutomation();
[DllImport("../Ayase.Accessibility.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetForeGroundWindowName();
参数啥的不必在意,看去看API就行。
关于配置和平台
善用配置管理器,如果只有Any CPU可以选择新建:
基本上都默认配好了,新平台的话下拉框里选就行。
注意:.dll 和 .NET 项目必须要同一个架构 (x64, x86, ARM64, ...)
注意
如果在cpp中用COM的接口和对象,需要import:
#include <combaseapi.h>






1 条评论
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com