在命令行上创建并链接到Win32 DLL的确切步骤是什么? [英] What are the exact steps for creating and then linking against a Win32 DLL on the command line?

查看:164
本文介绍了在命令行上创建并链接到Win32 DLL的确切步骤是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的库 Lib.c 文件:

#include <stdio.h>

int helloworld(){
    printf("Hello World DLL");
}

这是我的exe Main.c file:

Here's my exe Main.c file:

int helloworld();


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

我想创建 Lib.dll Main.exe ,其中 Lib.dll 来自 Lib .c Main.exe 链接 Lib.dll

I would like to create Lib.dll, and Main.exe, where Lib.dll comes from Lib.c and Main.exe links against Lib.dll.

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

What are the specific steps to achieve this?

推荐答案

请参阅相关问题如何建立该DLL。

See this related question on how to build the DLL.

您的库代码不会导出任何符号,您的可执行文件不会从您的库导入符号。两个典型的模式如下所示,但您可能希望先阅读。

Your library code as it stands does not export any symbols and your executable does not import the symbols from your library. Two typical patterns for doing that are shown below but you might want to read up on that first.

第一种方法使用 __ declspec()在代码中声明什么函数(或其他项目)从DLL导出并由其他可执行文件导入。您使用头文件来声明导出的项目,并具有用于控制符号是否为导出或导入的预处理程序标志:

The first method uses __declspec() to declare in the code what functions (or other items) are exported from your DLL and imported by other executables. You use a header file to declare the exported items and have a preprocessor flag used to control whether the symbols are exports or imports:

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函数一样(我可以使用 WINAPI 而不是 __ stdcall 如果我已经包括windows.h)并且已经将这些功能声明为 externC code>所以当编译为C ++时,他们的名字不会被弄脏。这不是一个这样的问题,因为它都是C,但是如果你要从C源构建DLL,然后尝试从C ++可执行文件使用它,那么导入的名称将是不正确的。

I have also specifically set the calling convention to __stdcall as are most DLL functions (I could have used WINAPI instead of __stdcall if I had included windows.h) and have declared the functions as extern "C" so their names do not get mangled when compiled as C++. Not such a problem here as it's all C, but if you were to build the DLL from C source and then try to use it from a C++ executable then the imported names would be incorrect.

代码可能如下所示:

mylib.c

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

int MYLIB_API helloworld(void)
{
    printf("Hello World DLL");
    return 42;
}

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

You'd build your DLL using the following command line. As well as creating the DLL it will create the import library (.lib) required to use your DLL from another executable (as well as the export file, but that is only required in certain circumstances):

cl /DBUILDING_MYLIB mylib.c /LD

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

The /DBUILDING_MYLIB argument defines the preprocessor symbol used to control whether the functions in the DLL are exports (if it is defined) or imports (not defined). So you'd define it when building the DLL but not when building your application.

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

The /LD parameter tells cl to produce a DLL.

第二种方法是使用模块定义文件,如评论中所述。您可以使用已有的代码,但您也需要创建模块定义文件。最简单的就是这样:

The second method is to use module definition files as mentioned in the comments. You can use the code you already have but you also need to create the module definition file. At it's simplest it looks like this:

LIBRARY   mylib
EXPORTS
   helloworld

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

In this case to build the DLL you require the following command line:

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

然后,您可以对应用程序进行编码,以便将库标题与导入的DLL函数一起使用:

You could then code your application so that it used your library header with the imported version of your DLL function:

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还是模块定义文件,此步骤都是一样的:

Which you could then compile with the following command line (assuming the import library from the DLL creation is in the same directory as your main.c). This step is the same whether you used declspec or module definition files:

cl main.c /link mylib.lib

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

Arguments passed after the /link argument are passed onto the linker command line as they appear, so as just a filename it is used as extra input to link into the executable. In this case we specify the import library generated when we built the DLL.

我在这里显示的命令行几乎是您需要的绝对最小值,但是'允许你创建一个DLL并链接一个应用程序。

The command lines I've shown here are pretty much the absolute minimum you'd need but it'll allow you to create a DLL and link an application to it.

我已经假定调用约定在上面所有都是正确的,我没有尝试过看看我是否在任何时候出错了。

I have assumed the calling convention is correct in all of the above and I have not experimented much to see whether I got it wrong at any point.

这篇关于在命令行上创建并链接到Win32 DLL的确切步骤是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆