Project1

标题: 利用Win32API.new()命令调用DLL时,怎么返回文本? [打印本页]

作者: 寒凌天    时间: 2019-10-26 17:14
标题: 利用Win32API.new()命令调用DLL时,怎么返回文本?
Win32API.new("dll", "_ceshi", ['i','i'], 'i')

上面i代表int,也就是整数型变量,这个我知道。但是怎么返回文本型变量呢?
作者: hyrious    时间: 2019-10-26 18:37
一般 api 会设计成传入一个由用户申请的空间,api 负责往里面填东西,比如,

假设是用 C 写的 dll,写一个 f 函数功能是填充 *:
  1. void f(char *buf, int size) { for (int i = 0; i < size; ++i) buf[i] = '*'; }
复制代码
那么 ruby 调用时:
  1. Win32API.new('a.dll', 'f', 'pl', 'v').call(buf = "\0" * 42, 42)
复制代码

当然,有的时候确实是 api 自己申请的字符串空间并返回地址(ruby 里会取到一个整数),这时候就要小心一点,
首先用 memcpy 或者 RtlMoveMemory 把 C 字符串从这个地址拿到 ruby 的一个字符串里,
然后记得自己 free 或者 api 提供 free 操作来释放空间
给一个参考实现:
  1. def ptr2str pointer
  2.   assert!(Integer === pointer)
  3.   len = api('kernel32', 'lstrlen').call pointer
  4.   return '' if len.zero?
  5.   str = [].pack("x#{len}")
  6.   api('kernel32', 'RtlMoveMemory').call str, pointer, len
  7.   str
  8. end
复制代码





欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1