Как объявить DLL в моде user32.dll (он же stdcall?)? - PullRequest
0 голосов
/ 05 октября 2011

У меня есть стороннее приложение, которое позволяет вам вызывать функции C из DLL-файлов. Приведенный пример этого приложения показывает, что вы можете позвонить в MessageBoxW из user32.dll. Это также позволяет вам вызывать функции C из ваших файлов DLL.

Я сделал DLL из файла file.h следующим образом:

_declspec (dllexport) void example(int);

и file.c вот так:

#include <stdio.h>
#include "file.h"

_declspec (dllexport) void example(int s1)
{
    printf("dsa");    
}

И скомпилируйте его с помощью компилятора C / C ++ версии 15 из Windows SDK следующим образом:

cl file.c /DLL /LD

И я получаю правильную компиляцию с файлом DLL. В экзаменаторе функций DLL я вижу свою функцию. Я помещаю этот файл в папку System32 и вызываю его из стороннего приложения.

Приложение находит файл, но не может найти функцию.

Я думаю, что причиной проблемы является то, что я объявляю (или компилирую) свою DLL другим способом / способом / стандартом, что библиотеки Windows (например, user32.dll), потому что user32.dll работает нормально.

Я обнаружил, что стороннее приложение использует такие функции вызова в DLL:

winapi_abi Используется для вызова системных функций Windows. Это объявлен как stdcall в Windows, но не имеет искаженных имен.

Итак, мой вопрос: как подготовить и скомпилировать файл DLL способом user32.dll (stdcall?), Чтобы он работал со сторонним приложением?

Ответы [ 4 ]

2 голосов
/ 05 октября 2011

Простой ответ:

__declspec(dllexport) void __stdcall example(int);

И то же самое в реализации, конечно.

Если вы посмотрите на windows.h и друзей, то увидите:

#define WINUSERAPI __declspec(dllexport)
#define WINAPI __stdcall

А затем:

WINUSERAPI int WINAPI MessageBoxW(HWND,LPCWSTR,LPCWSTR,UINT);

Но если вы просто определите несколько функций, вам не понадобятся макросы.

1 голос
/ 05 октября 2011

Включите файл .def, чтобы победить оформление имени stdcall.Тогда вы можете избавиться от беспорядка __declspec (dllexport).

0 голосов
/ 05 октября 2011

Спасибо всем. Решением было добавить файл def с экспортом, включить его в компилятор с помощью /DEF:file.def, использовать версию Remy (без #define _BUILDING ...) и удалить _stdcall.

0 голосов
/ 05 октября 2011

Вы не указываете никаких соглашений о вызовах в объявлении функции, поэтому компилятор по умолчанию будет __cdecl, который украшает экспортируемое имя.Кроме того, если вы компилируете в C ++ вместо C, происходит дополнительное декорирование.Чтобы обойти все это, вы должны сделать что-то вроде следующего:

file.h:

#ifndef fileH
#define fileH

#ifdef _BUILDING_DLL_
#define MYEXPORT __declspec (dllexport)
#else
#define MYEXPORT __declspec (dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

MYEXPORT void __stdcall example(int);

#ifdef __cplusplus
}
#endif

#endif

file.c:

#include <stdio.h>

#define _BUILDING_DLL_
#include "file.h"

void __stdcall example(int s1)
{
   printf("dsa");
}
...