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

Project1

 找回密码
 注册会员
搜索
查看: 2817|回复: 7

[已经解决] 请教API中函数参数类型的问题(不知道是不是这个问题= =)

[复制链接]

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
39357
在线时间
7471 小时
注册时间
2009-7-6
帖子
13482

开拓者贵宾

发表于 2011-1-24 13:33:04 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 fux2 于 2011-1-26 12:09 编辑

原句
  1. @GetPID = Win32API.new("user32","GetWindowThreadProcessId",['L'],'L')
  2. ppid = @GetPID.call(pid)
复制代码
不知道为何这里获得的ppid和VB中获取的不同,导致后面的工程无法继续,于是请假
是因为函数类型错误么?


另请教一下这里为什么会得到一个非定值的错误返回值?

点评

我说...这是VX相关吗?  发表于 2011-1-24 18:42
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托

Lv1.梦旅人

百合乡の蕾咪

梦石
0
星屑
50
在线时间
151 小时
注册时间
2011-1-12
帖子
198
发表于 2011-1-24 17:14:30 | 显示全部楼层
本帖最后由 蕾米莉亚·斯卡雷特 于 2011-1-24 19:09 编辑

DWORD GetWindowThreadProcessId(
  HWND hWnd,
  LPDWORD lpdwProcessId
);

确定没有写错?

Win32API.new("user32.dll", "GetWindowThreadProcessId", "lp", "l")



如果想获得 Ruby 运行的 PID 的话, 可以直接使用  $$ 来获取.

p $$

点评

不是获得本程序PID  发表于 2011-1-24 19:11
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
发表于 2011-1-25 02:02:17 | 显示全部楼层
本帖最后由 苏小脉 于 2011-1-25 02:02 编辑

参数类型声明写错了,你只声明了一个 'L' 参数,但实际上 GetWindowThreadProcessId 接受两个参数,一个是窗口句柄,一个是保存进程标识的指针(可为 NULL)。API 是本地函数,不存在参数默认值这样的高层概念,VB 这玩意儿可能是在 API 上面抽象了一层,实现了可选参数的机制,所以才可以只传递第一个参数。如果对本地函数也这么做,结果就是未知的。Windows API 遵循标准调用约定(stdcall),参数是从右到左压入栈中的。对于动态链接库函数调用这样的未经优化的代码,如果你只传递了一个参数给接受两个参数的函数,那在栈内存中本该是第二个参数的位置就没有被实际压入任何数据,但却保留着上一次使用这个位置的内存后遗留下来的值,所以对于函数调用者来说是不可知的,而且是可变的,这取决于整个程序帧在什么内存地址被装载。最后 GetWindowThreadProcessId 获取到的两个参数都是错误的值。

应该是:

@GetPID = Win32API.new("user32","GetWindowThreadProcessId",['L', 'p'],'L')
ppid = @GetPID.call(pid, 0)
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
39357
在线时间
7471 小时
注册时间
2009-7-6
帖子
13482

开拓者贵宾

 楼主| 发表于 2011-1-25 10:50:16 | 显示全部楼层
回复 苏小脉 的帖子

多谢苏大人赐教,但是此方法获得的pid还是与VB有出入(本次是3700和3704)
以至于玩呗后面的hProcess = @OpenPro.call(2035711,0,pid)无法取得正确值
还求继续详解
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
发表于 2011-1-25 11:40:22 | 显示全部楼层
回复 fux2 的帖子

没明白你想做什么,GetWindowThreadProcessId 返回的是创建了指定窗口的线程的标识,不是进程标识。如果同时需要进程标识,那需要给第二个参数传递一个有效的缓冲区指针,该 API 函数检测到这个指针不是 NULL,就会把进程标识拷贝到指针指向的内存中。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
39357
在线时间
7471 小时
注册时间
2009-7-6
帖子
13482

开拓者贵宾

 楼主| 发表于 2011-1-25 11:42:24 | 显示全部楼层
本帖最后由 fux2 于 2011-1-26 07:04 编辑

回复 苏小脉 的帖子

啊……
调用:
  1. if findwindow("扫雷")
  2.   cheat(openpro(getpid(findwindow("扫雷"))))
  3. end
复制代码
一共有如下方法
  1.   def findwindow(name)
  2.     buf = name * 1024
  3.     Win32API.new("kernel32", "MultiByteToWideChar", ['I', 'L', 'P', 'I', 'P', 'I'], 'I').call(65001, 0, "扫雷", -1, buf, 1024)
  4.     buf.strip!
  5.     isfind = @FindWindow.call(0, buf)
  6.     isfind == 0 ? false : isfind
  7.   end
  8.   
  9.   def getpid(pid)
  10.     return nil if pid == 0
  11.     ppid = @GetPID.call(pid, 0)
  12.     return ppid
  13.   end
  14.   
  15.   def openpro(pid)
  16.     p pid
  17.     return nil if pid == nil or pid == 0
  18.     hProcess = @OpenPro.call(2035711,0,pid)
  19.     hProcess == 0 ? false : hProcess
  20.   end
  21. def cheat(hProcess)
  22.     return false if hProcess == nil
  23.     baseaddr = 16798561
  24.     @Writeaddr.call(hProcess,baseaddr,0x41,1,0)
  25.   end
复制代码
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
发表于 2011-1-25 23:24:54 | 显示全部楼层
回复 fux2 的帖子

虽然你没给出你是如何调用方法的,但从你的方法命名来推断,你大概是把 GetWindowThreadProcessId 返回的线程标识传给 OpenProcess 了?OpenProcess 需要的是进程标识,所以你应该给 GetWindowThreadProcessId 传递一个有效的缓冲区地址,这样进程标识就会被拷贝到这个缓冲区中,然后再把它传给 OpenProcess。

点评

噢噢,忘了写了,=\\\=,6楼已更新  发表于 2011-1-26 07:03
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
发表于 2011-1-26 12:08:40 | 显示全部楼层
所以说你确实是把线程标识当作进程标识在用了嘛,正确做法:
  1.         buf = '    '
  2.     @GetPID.call(hwindow, buf)
  3.     pid = buf.unpack('I')[0]
复制代码
这个 pid 才是创建了 hwindow 所标识的窗口的进程 ID。

点评

噢啦多谢紫苏大人  发表于 2011-1-26 12:09

评分

参与人数 1星屑 +600 收起 理由
DeathKing + 600 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-3-29 22:41

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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