调用装饰函数 [英] Calling decorated functions

查看:46
本文介绍了调用装饰函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在VC ++中,我正在为未创建的外部DLL中的装饰函数调用而苦苦挣扎.我要使用的未经修饰的函数是:

In VC++ I''m struggling with calls to decorated functions in an external DLL which I did not create. The undecorated functions I''m trying to use are:

bool Orc::cCodecHuffman::fixedTable_decode_decompress(void *,unsigned int,void const *,unsigned int)
unsigned int Orc::cCodecHuffman::fixedTable_decode_getuncompressedlength(void const *,unsigned int)
void Orc::cCodecHuffman::fixedTable_decode_init(void const *,unsigned int)



我的函数原型的一个示例是:



An example of my function prototypes is:

int (__stdcall *_GetUncompressedLength) (int, int);
HMODULE hMyDLL = LoadLibrary("my.dll");

*(void**)&_GetUncompressedLength = GetProcAddress(hMyDLL, " -- decorated name -- ");

FUNC(unsigned int, GetUncompressedLength, (void* source, unsigned int sourceSz));



..宏"FUNC"定义为:



.. where the macro ''FUNC'' is defined as:

#define FUNC(ret, name, args) \
        extern "C" typedef ret (__stdcall *raw_##name) args; \
        raw_##name* name = (raw_##name*)&_##name;



调用这些函数的示例:



An example of calling these functions:

unsigned int NUMuBytes = (*GetUncompressedLength)( (void*)sourceBytes, csize );



有了这个,我很高兴自己不再得到
(a)访问违规,并且
(b)调试错误"ESP的值未在函数调用中正确保存".
但实际上上面的代码让我感到头疼.

1.)我应该为"Orc"和"cCodecHuffman"创建类原型吗?

2.)如果我使用模板"force_cast"功能指针(根据示例http://www.codeguru.com/cpp/wp/dll/importexportissues/article.php/c123),我似乎丢失了"__stdcall"约定,因为我收到一个调试错误"ESP的值未在函数调用中正确保存".如何避免这种情况?

3.)我不确定我是否正确解释了"GetUncompressedLength"的输出,因为这个数字太高了.
我收到指针了吗?

请注意,我正在尝试调用C ++成员函数:
(.有两个问题.第一个问题是C ++成员函数名称是修饰名称(指定extern" C无效).第二个问题是C ++语言规范不允许指针成员函数进行转换分为其他类型..)



With this, I''m happy that I''m no longer getting
(a) access violations, and
(b) the debug error "The value of ESP was not properly saved across a function call".
But in fact the code above is way over my head.

1.) Should I create class prototypes for ''Orc'' and ''cCodecHuffman'' ?

2.) If I use a template to ''force_cast'' the function pointers (according to the example http://www.codeguru.com/cpp/w-p/dll/importexportissues/article.php/c123), I seem to lose the ''__stdcall'' convention, because I get a Debug error "The value of ESP was not properly saved across a function call". How can I avoid this?

3.) I''m not sure whether I''m interpreting the output of ''GetUncompressedLength'' correctly, because the number is much too high.
Am I receiving a pointer?

Please note that I''m trying to call C++ member functions:
(".. There are two problems. The first problem is that C++ member function names are decorated names (Specifying extern "C" does not help). The second problem is that C++ language specifications do not allow pointer to member functions to be converted into other types..")

推荐答案



使用typedef具有可读代码,并使用标头的功能签名:
Hi,

Use typedef to have a readable code, and use the function signatures of your headers:
// typedef your function pointer
typedef unsigned int (__stdcall *pFnGetUncompressedLength) (void const *,unsigned int);
// declare a variable of that type
pFnGetUncompressedLength GetUncompressedLength = NULL;
HMODULE hMyDLL = LoadLibrary(_T("my.dll"));
// get the value from the dll
if (hMyDLL)
	GetUncompressedLength = (pFnGetUncompressedLength)::GetProcAddress(hMyDLL, "exported name");


然后只需通过变量调用函数即可:


Then just call the function through your variable:

if (GetUncompressedLength != NULL)
	int i = GetUncompressedLength(NULL, 0);


欢呼声,
AR


cheers,
AR


您似乎正在使事情变得不必要的复杂.要使用该函数,您需要一个函数指针,该指针将通过调用GetProcAddress()进行初始化,然后可以像正常函数调用一样使用该指针.因此,您的代码应如下所示(实际上我不确定您是否需要__stdcall限定符):
You seem to be making things more complicated than necessary. To use the function you need a function pointer which you will initialize by calling GetProcAddress() and you can then use that pointer just like a normal function call. Your code should thus look like (I''m not actually certain that you need the __stdcall qualifier):
int (__stdcall *_GetUncompressedLength) (void*, unsigned int);

HMODULE hMyDLL = LoadLibrary("my.dll");
_GetUncompressedLength = GetProcAddress(hMyDLL, " -- undecorated name -- ");
int result = _GetUncompressedLength(source, sourceSz);


其中sourcesourceSz是正确类型的变量.


where source and sourceSz are variables of the correct type.


这篇关于调用装饰函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆