我们一般调用动态库时,都需要依赖额外的dll库文件,需要考虑路径打包等问题,很不方便。如果能在强大的visual studio中用C语言写好需要的算法,通过机器码的形式给AHK调用,就可以解决打包等问题。
依赖的工具和脚本在这里下载
https://gitee.com/kazhafeizhale/Mcode4ahk
首先 需要修改 McodeGen.ahk 中VS工具路径 ,修改第75行 sVS := “C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\”替换成自己的路径
举个简单的例子
/*
MyFunction(int a, int b) {
return a + b;
}
MCode(MyFunction, "1,x64:8D0411C3")
*/
MCode(MyFunction, "1,x64:8D0411C3")
a := 100
b := 200
rtn := DllCall(MyFunction, "Int", a, "Int", b)
msgbox,% rtn
return
MCode(ByRef p, mcode)
{
static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
return
if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
return
p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
if (c="x64")
DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
return
DllCall("GlobalFree", "ptr", p)
}
如果我们要写一个 求和函数 MyFunction(int a, int b) ,按照如下步骤执行
- 执行脚本McodeGen.ahk ,输入 MyFunction(int a, int b) 函数,然后执行,中间会弹出一个edit,点击关闭后提示成功,此时MCode机器码已经复制到剪贴板
- 替换第八行的函数
- 按照DLL规则调用
McodeGen界面的设置一般只用关系x86和x64就行,其他默认
接下来说明如何把VS编译好的程序结果直接使用
- vs新建DLL工程
- 设置输出汇编
// Dll.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
extern "C" _declspec(dllexport) int test(int a, int b)
{
int c = a * b;
return c;
}
- 编译后打开cod后缀个格式的文件
- 复制需要的函数
- 执行McodeGen.ahk,当弹出edit编辑器时,用刚才内容替换保存
/*
MyFunction(int a, int b) {
return a + b;
}
MCode(MyFunction, "1,x64:8D0411C3")
*/
MCode(MyFunction, "1,x64:8D0411C3")
MCode(test, "1,x64:0FAFCA8BC1C3")
a := 100
b := 200
rtn := DllCall(MyFunction, "Int", a, "Int", b)
msgbox,% rtn
rtn := DllCall(test, "Int", a, "Int", b)
msgbox,% rtn
return
MCode(ByRef p, mcode)
{
static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
return
if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
return
p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
if (c="x64")
DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
return
DllCall("GlobalFree", "ptr", p)
}
新的Mcode就生成了