【发布时间】:2018-02-18 17:27:32
【问题描述】:
我正在寻找一组开发人员可以使用的库,他们可以决定是将它们用作动态库还是静态库。当然,这带来了几个复杂的问题,目前的问题是符号解析。在我的测试代码中,我有 3 个项目:可执行项目、静态项目和动态项目。顾名思义,静态工程编译成.lib,动态工程编译成.dll。
静态项目包含动态项目代码的头文件,并调用函数DynamicFunction,这意味着它会在编译时尝试链接到该函数。但是,正在编译到共享库的动态项目,它不可用,也没有链接。有没有办法让我在三个项目中定义函数来解决这个问题?
我的测试代码如下:
main.cpp - 编译成可执行文件
#include <Windows.h>
#include "../static/static.h"
using proc = void(*)();
proc p = 0;
// I tried using this to force there to be a DynamicFunction function to link with,
// But since they're in different compilation units, it doesn't quite work.
void DynamicFunction() {
if (p) {
p();
}
}
int main(int argc, char** argv) {
HMODULE dll = LoadLibrary("dynamic");
proc p = (proc)GetProcAddress(dll, "DynamicFunction");
UseDynamic();
}
静态.h
#pragma once
void UseDynamic();
静态.cpp
#include "../dynamic/dynamic.h"
#include "static.h"
void UseDynamic() {
DynamicFunction();
}
动态.h
#pragma once
extern "C" __declspec(dllexport) void DynamicFunction();
动态.cpp
#include "dynamic.h"
void DynamicFunction() {}
我认识到错误源于UseDynamic 假设函数也是静态定义的,但我不知道有什么方法可以让它知道函数是静态的还是动态的知道如何使用另一个库,甚至可能涉及一些丑陋的预处理器条件。
是否可以做我想做的事,或者我需要决定静态库还是动态库(或者至少不允许混合两者)
编辑:我正在使用 Visual Studio 2017
【问题讨论】:
-
当
main.o链接到可执行文件时,您是否确保将-ldynamic添加到链接器命令行?创建静态库不会抛出任何未定义的引用,因为它是一个不完整的链接,即生成的.lib不可执行并且不包含来自.dll的代码,即依赖链是main.exe -
我使用 Visual Studio,所以我对链接器的命令行选项不太熟悉,所以我不确定
-ldynamic是否适合它,但 Visual Studio确实可以选择强制文件退出,即使链接时存在未解析的符号。这会是你所说的行为吗?因为我不确定这将如何导致UseDynamic函数知道使用 dll 中的函数。 -
不,那是错误的做法。它将创建一个损坏的可执行文件,而不依赖于动态库。我不确定您是否可以在 VS GUI 中定义您需要的依赖项。我想您需要编写一个项目文件。如果我的记忆没有让我失望,那就是
.prj或.proj文件,然后您在 VS 中打开以创建工作区。 -
IIRC DLL 项目通常会构建一个静态导入库以及负责此操作的 DLL。将您的测试可执行文件链接到它,它应该可以工作。
-
@MilesBudnek 这似乎有效!您能否将其写为答案,以便我将其标记为正确?
标签: c++ dll static-libraries static-linking dynamic-linking