【问题标题】:VC++ 6.0: too many actual parametersVC++ 6.0:实际参数太多
【发布时间】:2012-06-07 20:31:32
【问题描述】:

我正在使用使用简单 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++ 中编译。

【问题讨论】:

  • VC 6?我强烈建议您将工具链更新为...以及其他任何东西。
  • 当它工作时你是编译成C,当它不工作时你编译成C++?
  • 是的,我们实际上正在将我们的平台(它依赖于几个在 VC6 之后从未正常运行的库)迁移到现代环境。
  • @ildjarn:我在 VC6 中同时编译,但工作代码包含在 .c 文件中,非工作代码包含在 .cpp 文件中,所以我相信是这样。
  • @Geo :好吧,您的代码显然是可编译的 C 但不可编译的 C++。你的实际问题是什么?

标签: c++ parameters compiler-errors visual-c++-6


【解决方案1】:

你需要为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, ...);

【讨论】:

  • 当我添加这个 typedef 时,我收到了与 shf301 的解决方案相同的错误:错误 C2440: '=' : cannot convert from 'unsigned short (__stdcall *)(unsigned short,unsigned short *,unsigned long *,unsigned long *,unsigned short *,unsigned short *,unsigned short *,unsigned short *,unsigned char *)' 到 'int (__stdcall *)(void)'
  • 更新包括更改dongle的类型。
  • 做到了。非常感谢!
【解决方案2】:

那篇文章正是您遇到的问题。在 C 中,列表中没有参数的函数定义是可以接受任意数量参数的函数。这实际上意味着编译器不会检查您传递给函数的参数的数量和类型。在 C++ 中,编译器总是检查传递给函数的参数的数量和类型。因此,您需要为函数调用使用具有正确数量和类型的参数的 typedef。

比如:

typedef WORD (CALLBACK* DONGLEPROC)(DWORD, LPWORD, LPDWORD , LPDWORD , LPWORD, LPWORD, LPWORD, LPWORD, LPBYTE);

【讨论】:

  • 我试过这个并收到一个额外的错误:错误 C2440: '=' : cannot convert from 'unsigned short (__stdcall *)(unsigned short,unsigned short *,unsigned long *,unsigned long *, unsigned short *,unsigned short *,unsigned short *,unsigned short *,unsigned char *)' 到 'int (__stdcall *)(void)',这让我相信仍然出于某种原因看到应该有没有参数。
  • 有趣的是,我还在 API 的头文件中找到了这一行: EXTERN_C __declspec(dllexport) WORD WINAPI SecureDongle(WORD function, WORD* handle, DWORD* lp1, DWORD* lp2, WORD* SD_p1, WORD * SD_p2, WORD* SD_p3, WORD* SD_p4, BYTE* 缓冲区);这个定义还不够吗?
猜你喜欢
  • 1970-01-01
  • 2011-09-29
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多