【问题标题】:DLL dependency to static libraryDLL 对静态库的依赖
【发布时间】:2018-10-16 08:59:20
【问题描述】:

我目前为我们的客户构建了一个纯静态MainLib,其中包含所有符号,以便他们可以将其集成到他们的程序中。出于多种原因,我现在需要提供 DLL 版本MainLib,其中包含部分符号与包含剩余符号的静态库 FeatureLib。一个原因是我们希望通过简单地窃取通过我们客户的程序提供的 DLL 来避免坏人使用我们的软件。如果部分符号通过静态库集成在调用软件中,这将不起作用。只有将FeatureLib 的符号添加到他的应用程序中,包的用户才能使用该DLL。

对于 Linux,我可以使这项工作像魅力一样,即符号doFeature() 不在libMainLib.so 内,但我在Windows 上没有成功。

CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)

project(MainLib)

add_library(FeatureLib STATIC src/FeatureLib.c)
target_include_directories(FeatureLib PUBLIC include
                                      PRIVATE src)

add_library(MainLib SHARED src/MainLib.c)
target_include_directories(MainLib PUBLIC include
                                   PRIVATE src)

# I don't want to include symbols from FeatureLib into shared MainLib
#target_link_libraries(MainLib PRIVATE FeatureLib)

add_executable(MainLibDemo src/demo.c)
target_link_libraries(MainLibDemo MainLib FeatureLib) #resolve symbol doFeature()

FeatureLib.h:

extern int doFeature(int input);

MainLib.h:

extern __declspec(dllexport) int MainLib(int input);

FeatureLib.c:

#include "FeatureLib.h"
int doFeature(int input) {return 4;}

MainLib.c:

#include "FeatureLib.h"
#include "MainLib.h"

__declspec(dllexport) int MainLib(int input)
{
  if (input > 2) {
    return doFeature(input);
  } else {
    return doFeature(0);
  }
}

demo.c:

#include <stdio.h>
#include <stdlib.h>

#include "MainLib.h"

int main(int argc, char **argv)
{
  if(argc > 1)
    return MainLib(atoi(argv[1]));
  else
    return 0;
}

这样,我得到以下编译错误:

"C:\Daten\tmp\DemoProject\simple\build\ALL_BUILD.vcxproj" (Standardziel) (1) ->
"C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj" (Standardziel) (4) ->
(Link Ziel) ->
  MainLib.obj : error LNK2019: unresolved external symbol _doFeature referenced in function _MainLib [C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj]
  C:\Daten\tmp\DemoProject\simple\build\Debug\MainLib.dll : fatal error LNK1120: 1 unresolved externals [C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj]

    0 Warnung(en)
    2 Fehler

这甚至可以在 Windows 上实现吗?我必须做什么才能使其工作,除了不将FeatureLib 链接到MainLibDemo 之外,我如何验证它。任何想法都非常受欢迎。

亲切的问候, 弗洛里安

【问题讨论】:

  • 关于如何解决这个问题的任何想法?
  • 您至少需要编辑您的帖子以显示“我在 Windows 上没有成功”的含义。
  • 感谢您的评论迈克。我在描述中添加了构建错误消息。
  • 您的问题有不一致的地方。你的CMakeLists.txtMainLib 是从C++ 源代码src/MainLib.cpp 构建的,但后来你说doFeature 在C 源代码MainLib.c 中被调用,错误消息表明MainLib.obj 是从C 编译的,而不是C++ ,因为对 _doFeature 的未解析引用尚未被命名。最好提供minimal reproducible example
  • 感谢迈克的反馈。我更新了描述,所以它只包含 C 代码并且是完整的。我希望它现在满足最小、完整和可验证的要求。给您带来的不便,我们深表歉意。

标签: c visual-studio dll cmake linker


【解决方案1】:

你在 Linux 下的方式在 Windows 下是行不通的 因为动态链接在这里的工作方式不同。 这是一种可行的策略。

MainLib.dll代码中,而不是直接调用doFeature 你需要定义一个适当函数的全局指针变量 指针类型并使用它来调用函数。 这将允许构建MainLib.dll 而不会出错。

现在你需要设置这个指针变量。一种方法是:

  • 将导出函数添加到接受指针的MainLib.dll 到可执行文件中 DLL 需要的所有函数。

  • FeatureLib.lib 代码中添加初始化函数 应用程序在使用之前需要调用 您的 DLL 会将指向其对等点的指针传递给 DLL。

这基本上是大多数带有插件的程序使用的方式 让插件访问他们的设施。

另一种方法是(警告!我没有测试过这个特定的 解决方案):

  • FeatureLib.lib中的函数声明为导出 与__declspec(dllexport)。这样它们将被导出 来自可执行文件。

  • MainLib.dll第一次使用指针之前使用 GetModuleHandleGetProcAddress 获取指针。 最好在一些初始化函数中完成 图书馆。否则,您需要注意避免竞争条件。

希望这会有所帮助。 尽管我认为您的版权保护计划不会奏效。 Andrew Henle 的评论是对的:这并不难 从一个可执行文件中提取所需的代码并包含它 在另一个。

【讨论】:

  • 感谢您的回答。但是,我需要在静态库旁边提供一个 DLL,以避免窃贼通过检查他们的 EXPORTS 来获取 DLL 并使用它。如果库的某些部分通过静态库分发给我们的客户,窃贼无法利用缺少这些符号的 DLL。
猜你喜欢
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多