2016-09-05 5 views
2

Im пытается вызвать экспортированную функцию из DLL, захватив ее указатель на функцию через GetProcAddress, но после вызова функции, с которой работает приложение.C++ WINAPI вызов экспортированной функции через GetProcAddress

Я использовал зависимого пользователя, чтобы узнать, имеют ли экспортированные функции правильное имя. Адрес, возвращаемый с GetProcAddress, не равен NULL. Я почти уверен, что это как-то связано с вызывающим соглашением, я использовал оба __cdecl и __stdcall, но не успел. Однако я бы хотел использовать GetProcAdress вместо __declspec(dllimport).

DLL # 1 (вызывающего абонента)

  • Linked DLL # 2.lib к этой DLL

    typedef void(__stdcall *ptr_init)(DWORD size); 
    
    ctx.hModule = LoadLibraryA("someDLL.dll"); 
    ptr_init init = (ptr_init)GetProcAddress(ctx.hModule, "init"); 
    
    if (init == NULL) { 
        out = out + " | init function is null"; 
    } else { 
        out = out + " | init function found!";//It is found 
    } 
    
    DWORD test = 10; 
    (*init)(test);//<-- makes application crash 
    

DLL # 2 (DLL, содержащий экспортируемой функции)

//header.h 
extern "C" __declspec(dllexport) void init(DWORD size); 

//source.cpp 
extern "C" __declspec(dllexport) void init(DWORD size) { 
    //code 
} 
+2

Вы не компилятор, чтобы помочь вам, когда вы получаете это неправильно. Похоже, вы ошиблись, это не выглядит очень __stdcall. В противном случае нет веских причин избежать использования отладчика. –

+0

Функция cdecl. Почему вы использовали stdcall. Не можете написать init (test). Проблема, скорее всего, в вашей DLL. Подумайте о создании MCVE. –

+0

* «Однако я бы хотел использовать' GetProcAdress' вместо '__declspec (dllimport)'. "* - Почему это было бы? Если вам нужно только контролировать, когда и как будут устранены импорт, вы можете использовать [delay-loading] (https://msdn.microsoft.com/en-us/library/151kt790.aspx) и обрабатывать разрешение импорта в ваш код (см. [Общие сведения о функции помощника] (https://msdn.microsoft.com/en-us/library/09t6x5ds.aspx)). – IInspectable

ответ

3

Вы должны быть последовательными. Если вы получить указатель, как указатель на stdcall функции - она ​​должна быть объявлена ​​как stdcall в реализации:

//header.h 
extern "C" __declspec(dllexport) void __stdcall init(DWORD size); 
+0

'__stdcall' заставляет приложение сбой, но удаляет все' __stdcall', почему? – MircoProgram

+0

Поскольку функция объявлена ​​в DLL-коде как '__cdecl'. –