设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2235|回复: 2
打印 上一主题 下一主题

[已经解决] 利用Win32API.new()命令调用DLL时,怎么返回文本?

[复制链接]

Lv3.寻梦者

梦石
0
星屑
3117
在线时间
205 小时
注册时间
2019-9-16
帖子
224
跳转到指定楼层
1
发表于 2019-10-26 17:14:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
Win32API.new("dll", "_ceshi", ['i','i'], 'i')

上面i代表int,也就是整数型变量,这个我知道。但是怎么返回文本型变量呢?

Lv4.逐梦者

梦石
0
星屑
9682
在线时间
570 小时
注册时间
2017-9-28
帖子
208
2
发表于 2019-10-26 18:37:15 | 只看该作者
一般 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
复制代码

点评

汗!原来这么复杂,我要消耗消化,先谢谢了。另外,我调用的时候确实返回的是疑似地址的整数  发表于 2019-10-26 18:56

评分

参与人数 1星屑 +50 +1 收起 理由
guoxiaomi + 50 + 1 精品文章

查看全部评分

喵喵喵
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-22 17:09

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表