我正在使用一个使用简单API的USB安全密钥。我所要做的就是包括他们的头文件并拨打我的电话。我有一个样本C程序可以正常工作,而且几乎可以做到这一点:
HINSTANCE hDll;
FARPROC dongle;
WORD retcode, handle[16], SD_p1, SD_p2, SD_p3, SD_p4;
DWORD lp1, lp2;
BYTE buffer [1024];
SD_p1 = 0x1C76; // example password 1
SD_p2 = 0x8078; // example password 2
SD_p3 = 0;
SD_p4 = 0;
hDll = GetModuleHandle("dongle.dll");
if (hDll == NULL)
{
hDll = LoadLibrary("dongle.dll");
if (hDll == NULL)
{
printf("Can't find dongle.dll\n");
return;
}
}
dongle = GetProcAddress(hDll, "dongle");
retcode = dongle(SD_FIND, &handle[0], &lp1, &lp2, &SD_p1, &SD_p2, &SD_p3, &SD_p4, buffer);
所以一切都正常。找到加密狗,后来调用加密狗的不同功能。但是,当我将这个完全相同的代码插入我想要保护的C ++应用程序时,我收到以下错误:
error C2197: 'int (__stdcall *)(void)' : too many actual parameters
这发生在retcode = dongle()调用上。我不明白为什么编译器会认为我的应用程序中有太多参数但在示例应用程序中没有。我找到了一个article与C#C ++中使用GetProcAddress()这种方式的区别,但我不确定这是否是我在这里看到的问题,或者我将如何应用该解决方案在这种特殊情况下。
我需要知道的是如何让这个C代码在C ++中编译。
答案 0 :(得分:2)
您需要为dongle
使用更好的类型定义:
/* I didn't know what type SD_FIND was, assumed DWORD */
typedef WORD (CALLBACK *DONGLEPTR)(DWORD,WORD*,DWORD*,DWORD*
,WORD*,WORD*,WORD*,WORD*,BYTE*);
DONGLEPTR dongle; /* <-- need to change this type as well */
/* ... */
dongle = (DONGLEPTR)GetProcAddress(hDll, "dongle");
/* ... */
retcode = dongle(SD_FIND, ...);
答案 1 :(得分:1)
那篇文章正是您遇到的问题。在C中,没有参数的函数定义列表是一个可以接受任意数量参数的函数。这实际上意味着编译器不会检查传递给函数的参数的数量和类型。在C ++中,编译器始终检查传递给函数的参数的数量和类型。因此,您需要为函数调用使用具有正确数量和类型参数的typedef。
类似于:
typedef WORD (CALLBACK* DONGLEPROC)(DWORD, LPWORD, LPDWORD , LPDWORD , LPWORD, LPWORD, LPWORD, LPWORD, LPBYTE);