在命令行上创建然后链接Win32 DLL的确切步骤是什么?

mer*_*011 10 c windows dll winapi native

这是我的库Lib.c文件:

#include <stdio.h>

int helloworld(){
    printf("Hello World DLL");
}
Run Code Online (Sandbox Code Playgroud)

这是我的exe Main.c文件:

int helloworld();


int main(int argc, char** argv){
    helloworld();
}
Run Code Online (Sandbox Code Playgroud)

我想创建Lib.dll,以及来自Main.exe哪里和链接.Lib.dllLib.cMain.exeLib.dll

实现这一目标的具体步骤是什么?

tin*_*man 20

对如何构建DLL相关的问题.

您的库代码不会导出任何符号,并且您的可执行文件不会从库中导入符号.这样做的两种典型模式如下所示,但您可能希望首先阅读.

第一种方法用于__declspec()在代码中声明从DLL导出并由其他可执行文件导入的函数(或其他项).您使用头文件来声明导出的项目,并使用预处理器标志来控制符号是导出还是导入:

mylib.h:

#ifndef MYLIB_H
#define MYLIB_H

#if defined(BUILDING_MYLIB)
#define MYLIB_API __declspec(dllexport) __stdcall
#else
#define MYLIB_API __declspec(dllimport) __stdcall
#endif

#ifdef __cplusplus
extern "C" {
#endif

int MYLIB_API helloworld(void);

#ifdef __cplusplus
}
#endif

#endif
Run Code Online (Sandbox Code Playgroud)

我还特别将调用约定设置__stdcall为大多数DLL函数(我本来可以使用WINAPI而不是__stdcall如果我已经包含了windows.h)并且声明了函数,extern "C"因此在编译为C++时它们的名称不会被破坏.这里没有这样的问题,因为它都是C,但如果你是从C源构建DLL然后尝试从C++可执行文件中使用它,那么导入的名称将是不正确的.

然后代码可能如下所示:

mylib.c

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

int MYLIB_API helloworld(void)
{
    printf("Hello World DLL");
    return 42;
}
Run Code Online (Sandbox Code Playgroud)

您将使用以下命令行构建DLL.除了创建DLL之外,它还将创建从另一个可执行文件(以及导出文件)使用DLL所需的导入库(.lib),但这只在某些情况下才需要:

cl /DBUILDING_MYLIB mylib.c /LD
Run Code Online (Sandbox Code Playgroud)

/DBUILDING_MYLIB参数定义用于控制DLL中的函数是导出(如果已定义)还是导入(未定义)的预处理程序符号.因此,您在构建DLL时定义它,而不是在构建应用程序时定义它.

/LD参数告诉cl生成DLL.

第二种方法是使用注释中提到的模块定义文件.您可以使用已有的代码,但还需要创建模块定义文件.它最简单,看起来像这样:

LIBRARY   mylib
EXPORTS
   helloworld
Run Code Online (Sandbox Code Playgroud)

在这种情况下,要构建DLL,您需要以下命令行:

cl /LD mylib.c /link /DEF:mylib.def
Run Code Online (Sandbox Code Playgroud)

然后,您可以编写应用程序代码,以便它使用库头和DLL函数的导入版本:

main.c中

/* No need to include this if you went the module definition
 * route, but you will need to add the function prototype.
 */
#include "mylib.h"

int main(void)
{
    helloworld();
    return (0);
}
Run Code Online (Sandbox Code Playgroud)

然后可以使用以下命令行进行编译(假设DLL创建中的导入库与main.c位于同一目录中).无论您使用的是declspec还是模块定义文件,此步骤都是相同的:

cl main.c /link mylib.lib
Run Code Online (Sandbox Code Playgroud)

/link参数传递到链接器命令行之后传递的参数,因为它只是一个文件名,它被用作链接到可执行文件的额外输入.在这种情况下,我们指定在构建DLL时生成的导入库.

我在这里显示的命令行几乎是您需要的绝对最小值,但它允许您创建DLL并将应用程序链接到它.

我已经假设调用约定在上述所有内容中都是正确的,并且我没有尝试太多来看看我是否在任何时候都弄错了.

  • 您应该更明确地了解创建.dll也会同时创建.lib的事实。 (2认同)