2009-10-29 48 views
1

我通过访问一个DLL:更换FAR通过什么和PASCAL通过__stdcall

int (__stdcall *Send) (char *); 
Send = (int (__stdcall *)(char *)) GetProcAddress(hmModule,"Send"); 

原来的呼叫使用:

int (FAR PASCAL *Send) (char FAR *); 
Send = (int (FAR PASCAL *)(char FAR *))GetProcAddress(hmModule,"Send"); 

有什么缺点的,并没有通过PASCAL FAR更换__stdcall

回答

3

删除FAR可能会限制所有模块在同一个段内。如果这是一个小程序,这可能很好。
编辑:但是FAR是过去的遗迹,不适用于win32目标,并且在大多数情况下安全删除。

更改调用约定,只会影响可能的调用这些方法的外部模块。 (它可能也有最小对性能的影响,但我甚至不确定)。

编辑:但是WOW ...! 不!无法完成,我没有注意到这是针对WinAPI方法的,也就是说,当调用约定很容易为您定义时...和FAR相同,可能需要。

第二天编辑,与HYA,任择议定书的其他详细信息
的目标函数是在WINDEF.H定义为

extern "C" int APIENTRY Send (LPCSTR sCmd) 

随着它支持很多的操作系统,编译器版本和本地定义的值,windef.h是一个组合逻辑练习[相当不错]。与 [非MAC]的路径,并假设WINDEF.H是在这方面的相对不变,APIENTRY归结为

... 
#define APIENTRY WINAPI 
... 
#define WINAPI __stdcall 

而且,由于为相同的路径,PASCAL也产生__stdcall第一“神秘” (即通常非MAC,MSC编译器8.0或更高版本(或编译器定义_STDCALL_SUPPORTED ...)

关于FAR或什么都没有,对我来说不那么清楚,但也是,windef.h宏中的大多数路径都会导致这两个宏产生任何东西,我认为这是因为编译器会使用目标内存模型来找出什么是短指针和长指针。无论如何,目标原型使用LPCSTR,即“远/长”指针,这可能是编译器生成的。同样,对于函数本身使用的FAR修饰符,这也是不必要的,编译器根据内存模型和/或隐式存根远程调用。

所以,上述解释了为什么,YES,所做的更改PASCAL__stdcallFAR不了了之都OK,应该导致功能性二进制。 (如果你改变编译器和/或目标操作系统,可能需要重新检查等等)。

非常感谢您提出这个问题,因为这促使我重温我在一段时间内没见过的问题。

+0

从PASCAL更改为StdCall不会影响性能,就好像该DLL被编译为允许StdCall(大多数)一样,那么访问方式也不会有任何区别。希望他明白FAR指的是位于与定义的指针起点不同的段中的地址。 – Reallyethical 2009-10-29 18:30:51

+0

@合理,对,谢谢你确认没有性能差异,并且在FAR上都可以。对于OP的确切需求,我有点困惑。大多数API都使用__stdcall(又名WINAPI),但是我从问题中得出的结论是,它目前可行,所以切换调用转换。会明确地破坏一些东西......也许我错过了一些' – mjv 2009-10-29 18:38:41

+0

今天下午,当我得到DLL时,我寻找一个工作示例,并在C中找到一个与旧FAR PASCAL通话。我怀疑代码是为以前版本的DLL编写的。 我刚看着源和APIENTRY(=> WINAPI => __ STDCALL)用于: 外部的 “C” INT APIENTRY发送(LPCSTR SCMD) 在WINDEF.H PASCAL定义为__stdcall,所以它解释为什么这两个工作(?)。 – anno 2009-10-29 23:42:14