如何以 user32.dll(又名 stdcall?)方式声明 DLL?

问题描述 投票:0回答:4

我有一个第三方应用程序,允许您从 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)的其他方式/方式/标准声明(或编译)我的 DLL,因为 user32.dll 工作正常。

我发现第三方应用程序在DLL中使用了这种调用函数:

winapi_abi 用于调用Windows系统函数。这些都是 在 Windows 上声明为 stdcall,但没有损坏的名称。

所以我的问题是:如何以 user32.dll 方式(stdcall?)准备和编译 DLL 文件,以便它可以与第三方应用程序一起使用?

c windows winapi dll
4个回答
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
投票

包含 .def 文件以阻止 stdcall 名称修饰。然后你就可以摆脱 __declspec(dllexport) 混乱。


0
投票

您没有在函数声明中指定任何调用约定,因此编译器将默认为

__cdecl
,它修饰导出的名称。 另外,如果您使用 C++ 而不是 C 进行编译,也会发生额外的装饰。 您需要在代码中执行类似以下操作来解决所有这些问题:

文件.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

文件.c:

#include <stdio.h>

#define _BUILDING_DLL_
#include "file.h"

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

0
投票

谢谢大家。解决方案是添加带有导出的 def 文件,通过 /DEF:file.def 将其包含在编译器中,使用 Remy 版本(不带 #define _BUILDING...)并删除 _stdcall。

© www.soinside.com 2019 - 2024. All rights reserved.