VC ++ 6.0: слишком много фактических параметров

Я работаю с USB-ключом безопасности, который использует простой API. Все, что мне нужно сделать, это включить их заголовочный файл и позвонить. У меня есть пример программы на 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 (). Я не понимаю, почему компилятор считает, что в моем приложении слишком много параметров, но их нет в примере приложения. Я нашел статью о разнице между использованием GetProcAddress () таким образом в C и C ++. , но я не уверен, является ли это проблемой, которую я здесь вижу, или как я бы применил это решение в этом конкретном сценарии.

Что мне нужно знать, так это то, как я могу заставить этот код C скомпилировать на C ++.


person Geo Ego    schedule 07.06.2012    source источник
comment
ВК 6? Я настоятельно рекомендую вам обновить свою цепочку инструментов, чтобы ... ну, на самом деле, что-нибудь еще.   -  person David Rodríguez - dribeas    schedule 08.06.2012
comment
Вы компилируете как C, когда он работает, и как C ++, когда он не работает?   -  person ildjarn    schedule 08.06.2012
comment
Да, мы действительно находимся в процессе переноса нашей платформы (которая зависит от нескольких библиотек, которые никогда не работали должным образом за пределами VC6) в современную среду.   -  person Geo Ego    schedule 08.06.2012
comment
@ildjarn: я компилирую оба в VC6, но рабочий код содержится в файле .c, а нерабочий код содержится в файле .cpp, так что я так считаю.   -  person Geo Ego    schedule 08.06.2012
comment
@Geo: Ну вот, ваш код, по-видимому, компилируемый C, но не компилируемый C ++. Какой у вас настоящий вопрос?   -  person ildjarn    schedule 08.06.2012
comment
Тогда мой вопрос будет заключаться в том, как я могу скомпилировать этот код C на C ++.   -  person Geo Ego    schedule 08.06.2012


Ответы (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, ...);
person user7116    schedule 07.06.2012
comment
Когда я добавил это typedef, я получил ту же ошибку, что и с решением shf301: error C2440: '=': cannot convert from 'unsigned short (__stdcall *) (unsigned short, unsigned short *, unsigned long *, unsigned long *, unsigned short *, unsigned short *, unsi gned short *, unsigned short *, unsigned char *) 'до' int (__stdcall *) (void) ' - person Geo Ego; 08.06.2012
comment
Обновлено, чтобы включить изменение типа dongle. - person user7116; 08.06.2012
comment
Это сработало. Спасибо большое! - person Geo Ego; 08.06.2012

Эта статья - именно та проблема, которая у вас возникла. В C определение функции без параметров в списке - это функция, которая может принимать любое количество параметров. Это фактически означает, что компилятор не проверяет количество и тип параметров, которые вы передаете функции. В C ++ компилятор всегда проверяет количество и тип параметров, переданных функции. Поэтому вам нужно использовать typedef с правильным количеством и типом параметров для вызова функции.

Так что-то вроде:

typedef WORD (CALLBACK* DONGLEPROC)(DWORD, LPWORD, LPDWORD , LPDWORD , LPWORD, LPWORD, LPWORD, LPWORD, LPBYTE);
person shf301    schedule 07.06.2012
comment
Я попробовал это и получил дополнительную ошибку: ошибка C2440: '=': невозможно преобразовать из 'unsigned short (__stdcall *) (unsigned short, unsigned short *, unsigned long *, unsigned long *, unsigned short *, unsigned short *, unsi gned short *, unsigned short *, unsigned char *) 'на' int (__stdcall *) (void) ', что наводит меня на мысль, что по какой-то причине все еще не должно быть параметров. - person Geo Ego; 08.06.2012
comment
Интересно, что я также нашел эту строку в файле заголовка API: EXTERN_C __declspec (dllexport) WORD WINAPI SecureDongle (функция WORD, WORD * дескриптор, DWORD * lp1, DWORD * lp2, WORD * SD_p1, WORD * SD_p2, WORD * SD_p3, WORD * SD_p4, BYTE * буфер); Разве этого определения не должно хватить? - person Geo Ego; 08.06.2012