A函数
foo
不管怎样
傅。obj公司
链接到DLL。
也许你可以指定
傅。obj公司
显式地在DLL的链接中。
也许你把
傅。obj公司
在静态库中,比如说
foobar.lib
,以及联动装置
的DLL包含对函数的一些引用
傅
. 然后链接器将
傅。obj公司
从
福巴。lib公司
并将其链接到DLL中,以解决
参考文献。
如果
傅。obj公司
通过从静态库中提取链接
完全一样
傅。obj公司
按名称链接。静态库只是
链接器可以从中选择需要携带的对象文件包
在联动装置上。链接完成后,生成的程序或DLL没有依赖关系
在静态库上。如果它需要包中的任何对象文件,它现在已经得到了它们。它不需要袋子。
下面是一个使用GCC mingw-w64工具链for Windows的示例,说明了
DLL导出的函数从静态库中链接:
C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0>echo off
Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.
C:\>cd develop\so\scrap
C:\develop\so\scrap>dir
Volume in drive C has no label.
Volume Serial Number is 16C7-F955
Directory of C:\develop\so\scrap
16/12/2017 17:50 <DIR> .
16/12/2017 17:50 <DIR> ..
16/12/2017 12:41 116 greeting.cpp
16/12/2017 12:42 99 greeting.h
16/12/2017 12:10 109 hello.cpp
16/12/2017 12:12 90 hello.h
16/12/2017 16:21 197 main.cpp
16/12/2017 12:25 117 niceday.cpp
16/12/2017 12:26 96 niceday.h
7 File(s) 824 bytes
2 Dir(s) 101,878,943,744 bytes free
你好清洁石油产品
#include "hello.h"
#include <iostream>
void hello()
{
std::cout << "Hello world!" << std::endl;
}
你好h
#ifndef HELLO_H
#define HELLO_H
extern __declspec(dllexport) void hello();
#endif
我们将编译
hello.cpp
:
C:\develop\so\scrap>g++ -Wall -c -o hello.obj hello.cpp
类似地:
祝你愉快。清洁石油产品
#include "niceday.h"
#include <iostream>
void niceday()
{
std::cout << "What a nice day!" << std::endl;
}
祝你愉快。h
#ifndef NICEDAY_H
#define NICEDAY_H
extern __declspec(dllexport) void niceday();
#endif
我们将编译
niceday.cpp
C:\develop\so\scrap>g++ -Wall -c -o niceday.obj niceday.cpp
现在我们将把这两个对象文件放在一个静态库中。
libgreet.lib
ar rcs libgreet.lib hello.obj niceday.obj
另一个源文件和头:
招呼清洁石油产品
#include "greeting.h"
#include "hello.h"
#include "niceday.h"
void greeting()
{
hello();
niceday();
}
招呼h
#ifndef GREETING_H
#define GREETING_H
extern __declspec(dllexport) void greeting();
#endif
我们还将编译:
g++ -Wall -c -o greeting.obj greeting.cpp
现在我们将创建一个DLL,
libgreeting.dll
,使用
greeting.obj
还有静电
图书馆
利布雷特。lib公司
:
C:\develop\so\scrap>g++ -shared -o libgreeting.dll greeting.obj libgreet.lib
这里有一个程序源文件:
#include "hello.h"
#include "niceday.h"
#include "greeting.h"
#include <iostream>
int main()
{
hello();
niceday();
std::cout << "I said..." << std::endl;
greeting();
return 0;
}
我们还将编译:
C:\develop\so\scrap>g++ -Wall -c -o main.obj main.cpp
最后,我们将通过链接
main.obj
具有
LIB问候语。dll
.
只有
具有
LIB问候语。dll
.
C:\develop\so\scrap>g++ -o prog main.obj libgreeting.dll
运行程序:
C:\develop\so\scrap>prog
Hello world!
What a nice day!
I said...
Hello world!
What a nice day!
所有三个DLL导出函数,
hello
,
niceday
和
greeting
,
被称为。
所有这些都很重要
为了实现这一点,他们都是
宣布
__declspec(dllexport)
所有这些都与
LIB问候语。dll
以某种方式
. 碰巧有两个(
你好
,
尼斯戴
)从静态库和另一个(
招呼
)直接从对象文件链接:这无关紧要。
如果你有兴趣。。。
下面是如何使用Visual Studio 2017工具链执行相同操作:
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.4.3
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
C:\Users\mikek\source>cd C:\develop\so\scrap
C:\develop\so\scrap>dir
Volume in drive C has no label.
Volume Serial Number is 16C7-F955
Directory of C:\develop\so\scrap
16/12/2017 18:31 <DIR> .
16/12/2017 18:31 <DIR> ..
16/12/2017 12:41 116 greeting.cpp
16/12/2017 12:42 99 greeting.h
16/12/2017 12:10 109 hello.cpp
16/12/2017 12:12 90 hello.h
16/12/2017 16:21 197 main.cpp
16/12/2017 12:25 117 niceday.cpp
16/12/2017 12:26 96 niceday.h
7 File(s) 824 bytes
2 Dir(s) 101,877,473,280 bytes free
编写
你好清洁石油产品
:
C:\develop\so\scrap>cl /W4 /EHsc /c /Fohello.obj hello.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
hello.cpp
编写
祝你愉快。清洁石油产品
:
C:\develop\so\scrap>cl /W4 /EHsc /c /Foniceday.obj niceday.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
niceday.cpp
创建静态库:
C:\develop\so\scrap>lib /out:libgreet.lib hello.obj niceday.obj
Microsoft (R) Library Manager Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
编写
greeting.cpp
:
C:\develop\so\scrap>cl /W4 /EHsc /c /Fogreeting.obj greeting.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
greeting.cpp
链接
LIB问候语。dll
:
C:\develop\so\scrap>link /dll /out:libgreeting.dll greeting.obj libgreet.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library libgreeting.lib and object libgreeting.exp
如您所知,在这里,Microsoft linker创建了一个
导入库
libgreeting.lib
利布雷特。lib公司
)用于
链接
LIB问候语。dll
到程序或其他DLL。
编写
main.cpp
:
C:\develop\so\scrap>cl /W4 /EHsc /c /Fomain.obj main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
链接我们的程序(使用导入库
LIB问候语。lib公司
代替
LIB问候语。dll
):
C:\develop\so\scrap>link /out:prog.exe main.obj libgreeting.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
并运行:
C: \开发\销售订单\报废>掠夺
你好,世界!
多好的一天啊!
我说。。。
你好,世界!
多好的一天啊!
后来
如果
傅
第一次编译时没有
__declspec(dllexport)
有这样的声明
void foo()
当我构建B.lib时。
但是当我构建C.exe时,我将foo的声明更改为
__declspec(dllexport) void foo()
. 问题是,我还能做到这一点吗?
原则上,如果编译具有特定声明的对象文件
傅
在其头文件中
然后
改变
该声明随后
#include
中的头文件
编译其他一些对象文件,那么您很可能在
可以预料坏事会发生。
然而,在这种情况下,你可以逍遥法外。在上面的示例中,您
可以先编译,
你好清洁石油产品
在声明中
hello.h
:
extern void hello(void);
稍后,当您编译时
招呼清洁石油产品
哪一个
#包括
s
你好h
你
可将声明更改为:
extern __declspec(dllexport) void hello(void);
你好
将
链接时导出DLL\U
LIB问候语。dll
.
声明与
__declspec(dllexport)
精炼而不是矛盾
没有的那个。在链接中
LIB问候语。dll
,链接器会看到非DLL导出的引用
你好
在里面
hello.obj
以及在中导出的DLL引用
招呼obj公司
. 它
DLL导出符号,因为它至少看到一个DLL导出的引用。
毫无疑问,这是一个
乱劈
.