# 写在前面
- 在.Net FrameWork 时代,本人常用的导出函数的方式为 DLLExport,但是.Net 技术发展太快,项目作者没有继续跟进高版本的.Net 版本,最高支持到似乎是.NetCore2.1,对于这个版本以下的项目使用这个项目完全足够,不过只限于 Windows 平台
- DNNE 使用方法对于
DLLExport更复杂一些,不过高版本也没得选。DNNE 提供跨平台编译,不只限于 Windows 平台,且要求.Net6 以上
# 函数导出表
PE 文件有导入表与导出表,导入表是引入其他 PE 文件的函数,导出表是本文件向其他文件提供的函数入口表。对于大部分的查壳工具或是 PE 文件工具都提供了导出表以及导入表的查看。
旧酷 Q 插件即使从 cpk 文件解包出来也无法直接使用的原因就是,酷 Q 在打包插件的时候就将导出表抹除了,所以在兼容框架初期,有人手动从 DLL 文件手动找函数入口,补全了导出表,并使插件工作正常。(我见过的是回溯的骰娘,找了找没找到文件,展示不了力)
# DLLExport
# 安装方式
# Nuget
- 在 Nuget 包管理器内直接搜索
DllExport Install-Package DllExport
在弹出的窗口勾选需要进行函数导出的项目,选择右上角的 Apply 即可
# .bat
(我上传键呢)
放在项目根目录之后打开即可,在下载自己的依赖之后,会打开上一步弹出的窗口,相同操作
# 函数导出
# 最小示例
1 | [] |
编译之后就有了名为 test 的导出函数
# 规定名称
1 | [] |
这样就有了名为 TestFunction 的导出函数
# 复杂对象
参数以及返回值都需要使用 struct 而不应该使用 class
# string
# 简易
1 | IntPtr intPtr = Marshal.StringToHGlobalAnsi(str); |
使用系统默认编码,编码格式受限
# 编码 (GB18030 示例)
1 | Encoding GB18030 = Encoding.GetEncoding("GB18030"); |
# 解码(GB18030 示例)
1 | [] |
# 实用部分
# 输出导出表
.\DllExport.bat -pe-exp-list
1 | PS E:\DO\ClassLibrary1\ClassLibrary2\bin\Debug\net7.0> .\DllExport.bat -pe-exp-list ClassLibrary2NE.dll |
# 命令行代替窗口
这个可能更适用于类似 GitHub Action 的自动化操作.\DllExport -action Restore
# DNNE
# 依赖
https://github.com/AaronRobinsonMSFT/DNNE#dnne-nupkg-requirements
# 安装
- 在 Nuget 包管理器内直接搜索
DNNE Install-Package DNNE
# 代码
# 最小示例
1 | [] |
这样便导出名为 test 的函数
# 规定名称
1 | [] |
这样就有了名为 TestFunction 的导出函数
# x86
AnyCPU 与 x86 导出上略有不同
1 | [] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] |
之后…… 编译就失败了
1 | 1> 正在创建库 E:\DO\ClassLibrary1\ClassLibrary2\obj\x86\Debug\net7.0\dnne\bin\ClassLibrary2NE.lib 和对象 E:\DO\ClassLibrary1\ClassLibrary2\obj\x86\Debug\net7.0\dnne\bin\ClassLibrary2NE.exp |
解决方案就是规定生成平台为 win-x86
- 打开项目
.csproj文件 - 在
PropertyGroup添加一项<RuntimeIdentifier>win-x86</RuntimeIdentifier>![file]()
# 复杂对象
参数以及返回值都需要使用 struct 而不应该使用 class
# string
DNNE 也不支持直接 string 返回,查阅上一章的 string 部分
# .Net FrameWork 兼容?
兼容不好,由于二者使用的部分项目集名称相同但版本号不同,使用.Net7 程序可以正常加载.netFramework 文件,但是调用时就会发生异常,不过有时候也没事,就体验来说是可能反射时发生的异常。
若想彻底解决问题,就需要把.netFramework 程序改为.netStandard 编译(咋可能
# 部署
此文件生成出来是不能只把 dll 拿走就用的,需要连着原来的 dll 以及运行 json 一起拿走
CQPNet7.dll 以及 CQPNet7.runtimeconfig.json 都是原项目生成的,这三个文件需要在一起才能正常运作
# 生成改名
生成出来的文件是有 NE 后缀的,这个可以配置
1 | <PropertyGroup> |
这样改之后,生成的文件就是 CQP.dll 了

