最近一直在做的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>

Reference

最后修改:2021 年 08 月 04 日 12 : 23 AM
真的不买杯奶茶嘛....qwq