[疑难] D的调用协议
player7
2007-08-23
问题如下:我调用HGE.dll里的函数
在HGE的C++头文件中,有这样的虚函数 virtual void __STDCALL System_Log(const char *format, ...) = 0; 我把它直接翻译成了: extern(Windows) void System_Log(char *format, ...); 一直用了很长时间也没啥问题,但是今天才想起来STDCALL是怎么实现可变参数的啊??? 这样的话,D里面的 Windows 调用协定能和它共同工作吗??? |
|
achun
2007-08-23
查了一下:
_stdcall是Windows API函数中默认的调用约定. extern(Windows)正好呼应, _stdcall将参数压栈是按C语言的顺序(从右到左),但与C 语言不同的是它是由被调用者将参数从栈中清除的. 可变参数............ 猜测也在Windows API函数调用约定中吧.基于约定的东西.... 另外在delphi中根本就没有可变参数,但是一样能与c/c++写的可变参数函数传递数据, 用的是:(抄一段) function WriteLog(s:PChar):integer;stdcall;varargs;external 'MYDLL.dll'; 可见一斑呀............... |
|
oldrev
2007-08-24
D没有明确支持C++ ABI,感觉用这个不太靠谱。
这个类是不是 COM 接口? |
|
player7
2007-08-24
现在的问题,现在到底是谁在清栈呀?
按规定应该是C++那边在清栈吧,可是它怎么知道是几个参数呢? |
|
player7
2007-08-24
我不太懂呀,全部是纯虚函数,应该算是模仿COM的吧?
|
|
achun
2007-08-24
没有那么复杂吧.看看这个
http://www.pconline.com.cn/pcedu/empolder/gj/c/0411/484715.html 因为他的第一个参数是format,所有正好可以通过解析获取可变参数的类型.换句话说其实第一个参数中已经包含了其他参数的信息了. 理论上这中调用仍然是不可靠的.好像那本数上说过记不清了. 虚函数和参数传递没有关系呀. |
|
achun
2007-08-24
从这一点上也可以看出,我们写的所有函数间的参数传递,
实际上运行期并没有什么安全的检查,都是约定式的. 要说有检查那也是编译期的. |
|
oldrev
2007-08-24
Windows调用约定 __stdcall 是不支持可变参数的,只有 C调用约定 __cdecl 才支持。
|
|
player7
2007-08-24
是的,所有现在我搞不清了,
virtual void __STDCALL System_Log(const char *format, ...) = 0; 到底是哪一种调用? 为什么它能通过编译器检查? |
|
player7
2007-08-24
我想了一下,是不是这样的:
正常的可变参数用cdecl,调用者清栈,被调用者只管使用参数即可;这样从编译器里保证了清栈的正确性. 而stdcall是由被调用者清栈,他根据的是 format字符串参数来清栈,这样,必须人工的保证字符串中" %"的个数与可变参数的个数相匹配,否则就会出错. 所以,D语言用 Windows协议就可以正常工作,因为调用方不用任何责任; 但是,安全性太低了. |
相关讨论
相关资源推荐
- VB实现FTP功能程序源码
- 用VB6写简单的FTP上传程序
- 利用VB实现FTP基本功能.doc
- VB程序员的FTP编程指南1.7-用VB实现FTP的一个例子(大结局) (转)
- VB程序员的FTP编程指南1.5-其它的ftp支持命令
- java杂谈之--Swing观感(look & feel)
- java Swing 修改外观(LookAndFeel)的方法
- java lookandfeel下载_java内置的几种UI外观 更改皮肤(LookAndFeel)
- java lookandfeel nimbus_动态改变LookAndFeel
- javax.swing自带的几种显示风格.使用LookAndFeelInfo查看