我是一个港口程序员,我需要知道如何在同一个普通C函数中使用不同的调用约定,因为一些DLL制造商使用__stdcall,另一个使用__cdecl,但是函数是相同的,例如:
static int iCcv = 1;
HB_FUNC( foo )
{
if( iCcv == 1 )
typedef const char * ( __stdcall * pMYFUNC )( int n );
else
typedef const char * ( __cdecl * pMYFUNC )( int n );
pMYFUNC funcMy = (pMYFUNC) GetProcAddress( hLib, "myProc" );
const char * ret;
if( funcMy )
ret = funcMy( hb_parni( 1 ) );
hb_retc( ret );
}发布于 2022-09-05 20:53:10
你需要的东西更像:
const int CALLING_STDCALL=1;
const int CALLING_CDECL=2;
typedef const char * ( __stdcall * pMYFUNC_STDCALL )( int n );
typedef const char * ( __cdecl * pMYFUNC_CDECL )( int n );
//... The init() function where the library is linked...
int init(FARPROC* my_func){
*my_func=GetProcAddress( hLib, "myProc" );
if(*my_func==NULL){
return -1;
}
return 0; //Always check you loaded successfully!
}
//.. to call it
const char *CallMyFunc(FARPROC pFunc,int n,int conv){
assert(pFunc!=NULL);//Should never get this far badly loaded.
if(conv==STDCALL){
pMYFUNC_STDCALL func=(pMYFUNC_STDCALL)pFunc;
return pFunc(n);
}
assert(conv==CALLING_CDECL);//Good measure!
pMYFUNC_CDECL func=(pMYFUNC_CDECL)pFunc;
return pFunc(n);
}这里的“魔力”是,将生成调用这两个约定的代码,并执行相关版本(假设标志设置正确--这不是问题所在!)
没有像泛型函数指针那样的东西(尽管您可以在函数指针类型之间往返函数指针),而且在C语言中也不能保证void *将执行(*)。但在Windows上,FARPROC正是为此目的而提供的。在平台中定义了行为,以便将FARPROC转换为正确的类型。
通过将指针封装在一个安全的struct中,更多的类型安全性会使上面的内容受益,但我认为这可能会掩盖本质。
请。请!一定要进行大量的错误检查,并且可能会将我的调试asserts()提升到永久的版本构建检查。
在这样一个地方工作过,那里的外设和DLL比比皆是,它们并不总是按照他们在盒子上说的那样做,所以在诊断方面的任何帮助都是值得的。
(*)虽然在现代平台上通常是这样的。
https://stackoverflow.com/questions/73614147
复制相似问题