选择本文使用的编译器: ,本文平台:Windows 10
int __stdcall add(int a, int b) { return a + b; }
编写 .def 文件
EXPORTS
add
编译
cl /LD a.c /link /def:a.def
clang -m32 -shared a.c -o a.dll -Wl,-def:a.def
gcc -m32 -shared a.c -o a.dll
调用
Win32API.new('a.dll', 'add', 'll', 'l').call(3, 5) #=> 8
导入导出参数类型只能使用 VPpNnLlIi
,调用约定使用 stdcall,系统函数四字节对齐
举例:MessageBox
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
MessageBox = Win32API.new('user32', 'MessageBox', 'LppL', 'L')
MessageBox.call(0, 'content', 'title', 16)
举例:GetCursorPos
BOOL GetCursorPos(LPPOINT lpPoint);
GetCursorPos = Win32API.new('user32', 'GetCursorPos', 'p', 'L')
GetCursorPos.call(doubleL = "\0" * 8)
point = doubleL.unpack('LL') #=> [12, 34]
常用方法
# 移除末尾空格和 "\0"
"asd \0\0\0".unpack('A*') #=> "asd"
# 移除末尾 "\0"
"asd \0\0\0".unpack('Z*') #=> "asd "
# 添加 "\0";注意,使用 WideChar 时可能要添加两个 "\0"
["asd"].pack('Z*') #=> "asd\0"
["asd\0"].pack('Z*') #=> "asd\0\0"
# ASCII 范围内的 UTF-8/WideChar 互换
'hello'.unpack('U*').pack('S*') #=> "h\0e\0l\0l\0o\0"
"h\0e\0l\0l\0o\0".unpack('S*').pack('U*') #=> 'hello'
# 强行使用二进制编码(防止 UTF-8 编码报错)
"hello".b
gcc -w -m32 -c -O -fno-ident a.c
objcopy -O binary -j .text a.o a
8b44 2408 0344 2404 c3
objdump -M intel -S a.o
00000000 <_Add>:
0: 8b 44 24 08 mov eax,DWORD PTR [esp+0x8]
4: 03 44 24 04 add eax,DWORD PTR [esp+0x4]
8: c3 ret
CallWindowProc = Win32API.new 'user32', 'CallWindowProc', 'pLLLL', 'L'
CallWindowProc.call [
0x8b, 0104,0044, 8, # [1] mov 8(%esp), %eax
0x03, 0104,0044, 4, # [0] add 4(%esp), %eax
0xc2, 16,0, # ret $16
].pack('C*'), 3, 5, 0, 0 # => 8
int compare_ints(const void* a, const void* b) {
int arg1 = *(const int*)a;
int arg2 = *(const int*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int ints[] = { -2, 99, 0, -743, 2, INT_MIN, 4 };
int size = sizeof ints / sizeof *ints;
qsort(ints, size, sizeof(int), compare_ints);
等价 Ruby 写法
compare_ints = [
%w[ 8b44 2404 8b10 8b44 2408 8b00 39c2 7c07
0f9f c00f b6c0 c3b8 ffff ffff c390 9090 ].join
].pack('H*')
ints = [ -2, 99, 0, -743, 2, -2147483648, 4 ].pack('l*')
size = 7
dll('msvcrt').qsort(ints, size, 4, compare_ints)
ints.unpack('l*')
#=> [-2147483648, -743, -2, 0, 2, 4, 99]
以 AsHttp 为例,导出诸如 GetState 等同步函数,对应 RGSS 脚本
其他例子:
© 2019 hyrious