首页
社区
课程
招聘
[讨论]Delphi和VC中一个比较奇怪的回调函数问题
发表于: 2006-12-5 19:59 5467

[讨论]Delphi和VC中一个比较奇怪的回调函数问题

2006-12-5 19:59
5467
最近给一个delphi的程序插件。
因为对delphi不熟,就打算用vc来写。郁闷的是sdk只有delphi的。
其中遇到一个回调函数,郁闷坏了;
sdk中回调函数的原型
TCreateMenu = function(Window: IWindow; Parameters: PWideChar): IMenu; stdcall;

我看这个是stdcall应该很好转成vc的。

就定义了函数
IMenu* __stdcall myCreateMenu(IWindow* Window, BSTR Parameters)
{
....
}
把这个函数地址传给主程序,然后就崩溃了。

为了测试我用delphi建了一个简单的项目
定义函数如下
function myCreateMenu(Window: IWindow; Parameters: PWideChar): IMenu; stdcall;
begin
  ...
end;

然后拿这个测试,运行正常。

都是stdcall的函数,vc那个不正常,delphi的正常。
没办法,对delphi不熟,delphi函数编译后什么样子也不太清楚,
就拿od跟一跟,
发现一个奇怪的问题。
就是 vc的函数最后 ret 08 这个很好理解。
可是 delphi的那个函数最后 ret 0C ,这是怎么回事,明明只有两个参数?!
然后加了一些测试代码,发现 在delphi的函数里面,如果按照三个参数来理解
那么Window应该是第二个参数,Parameters是第三个参数.

于是我把 VC的那个函数改成三个参数,在最前面增加了一个参数。
编译测试,程序可以运行,不崩溃了,但是效果不对。

如是就有跟了一下delphi的那个函数,发现返回值放在第一个参数里面的。

如是再改
IMenu* __stdcall myCreateMenu(IMenu**ret, IWindow* Window, BSTR Parameters)
{
....
}
把返回值付给ret,编译运行正常了。

那位大大对delphi熟悉的,帮忙解解惑啊,delphi编译函数时会改变函数原型的?或者有什么规则?
(我用的是delphi7)

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
2
delphi这边应该没有问题。你不妨试试反汇编看看IMenu* __stdcall myCreateMenu(IWindow* Window, BSTR Parameters)和delphi的插件编译出来是什么样子

既然指定了stdcall,delphi就会按照stdcall的约定来。
2006-12-6 08:24
0
雪    币: 288
活跃值: (112)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
3
用ida看了。
VC的那个正常的,反汇编后显示是两个参数。
delphi的,
function myCreateMenu(Window: IWindow; Parameters: PWideChar): IMenu; stdcall;
begin
  ...
end;

反汇编后看有三个参数;

另外还想问一个问题

function GetUID(): Int64;
begin
  ...
end;

这样的函数delphi里面,返回值是放在哪里的?
2006-12-6 13:27
0
雪    币: 222
活跃值: (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
一般的约定不是EAX低位,EDX高位吗?
2006-12-6 13:37
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
5
stdcall正常的ret应该是在eax/edx:eax

如此,vc肯定是对的

奇怪了。我接触到的delphi程序stdcall都是对的啊。莫非是涉及到类成员方法?

我以前翻译过一篇逆向delphi类的东西,你的描述和它很象。
2006-12-7 16:26
0
雪    币: 288
活跃值: (112)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
6
在delphi里面 IMenu 可能是一个对象,
它会不会是因为返回值是对象,就放在第一个参数里面返回的了?

另外还遇到同类型的问题。

delphi里面是
GetName() :WideString

在vc里面就要写成
GetName(BSTR** result);
这能正常运行。
2006-12-7 19:01
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
7
可能是因为对象的原因吧
2006-12-9 20:08
0
游客
登录 | 注册 方可回帖
返回
//