在命令行上创build并链接到Win32 DLL的确切步骤是什么?

这是我的库Lib.c文件:

 #include <stdio.h> int helloworld(){ printf("Hello World DLL"); } 

这是我的exe Main.c文件:

 int helloworld(); int main(int argc, char** argv){ helloworld(); } 

我想创buildLib.dllMain.exe ,其中Lib.dll来自Lib.cMain.exe链接。

具体步骤是什么?

请参阅有关如何构建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 

我也特别将调用约定设置为__stdcall就像大多数DLL函数一样(如果我包含了windows.h,我可以使用WINAPI而不是__stdcall ),并且声明了函数作为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; } 

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

 cl /DBUILDING_MYLIB mylib.c /LD 

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

/LD参数告诉cl产生一个DLL。

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

 LIBRARY mylib EXPORTS helloworld 

在这种情况下建立DLL需要下面的命令行:

 cl /LD mylib.c /link /DEF:mylib.def 

然后,您可以编写您的应用程序,以便使用您的库头与您的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); } 

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

 cl main.c /link mylib.lib 

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

我在这里显示的命令行几乎是绝对最小的,但它可以让你创建一个DLL并将应用程序链接到它。

以上所有的调用惯例都是正确的,而且我也没有做过多的尝试,看看我是否在任何时候都搞错了。