我有第三方应用程序,允许您从DLL文件中调用C函数。提供此应用程序的示例显示您可以从user32.dll调用MessageBoxW。它还允许您从DLL文件中调用C函数。
我从file.h文件中做过这样的DLL:
_declspec (dllexport) void example(int);
和file.c像这样:
#include <stdio.h>
#include "file.h"
_declspec (dllexport) void example(int s1)
{
printf("dsa");
}
使用来自Windows SDK的C / C ++编译器版本15进行编译,如下所示:
cl file.c /DLL /LD
我可以使用DLL文件进行适当的编译。在DLL函数考官中,我看到了我的功能。我将此文件放入System32文件夹并从第三方应用程序中调用它。
应用程序找到该文件,但无法找到该函数。
我认为问题的原因是我以其他方式/方式/标准声明(或编译)Windows库(如user32.dll)因为user32.dll工作正常。
我发现第三方应用在DLL中使用了这种调用函数:
winapi_abi用于调用Windows系统函数。这些是 在Windows上声明为stdcall,但没有错位。
所以我的问题是:如何以user32.dll方式(stdcall?)准备和编译DLL文件,以便它可以与第三方应用程序一起使用?
答案 0 :(得分:2)
简单的答案是:
__declspec(dllexport) void __stdcall example(int);
当然,在实施中也是如此。
如果您查看windows.h
和朋友,您会看到:
#define WINUSERAPI __declspec(dllexport)
#define WINAPI __stdcall
然后:
WINUSERAPI int WINAPI MessageBoxW(HWND,LPCWSTR,LPCWSTR,UINT);
但是如果你只定义一些函数则不需要宏。
答案 1 :(得分:1)
包含.def文件以阻止stdcall名称修饰。然后你就可以摆脱__declspec(dllexport)的混乱。
答案 2 :(得分:0)
您没有在函数声明中指定任何调用约定,因此编译器将默认为__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");
}
答案 3 :(得分:0)
谢谢大家。解决方案是添加带有导出的def文件,通过/DEF:file.def将其包含在编译器中,使用Remy版本(不带#define _BUILDING ...)并删除_stdcall。