简体   繁体   English

DLL对静态库的依赖

[英]DLL dependency to static library

I currently build a purely static library MainLib for our customers that contains all symbols so that they can intrgrate it into their program. 我目前为客户构建一个纯静态的 MainLib库,其中包含所有符号,以便他们可以将其集成到他们的程序中。 For several reasons, I now need to deliver a DLL version of MainLib that contains parts of the symbols alongside a static library FeatureLib that contains the remaining symbols. 由于多种原因,我现在需要提供MainLib 的DLL版本 ,其中包含部分符号以及包含其余符号的静态库 FeatureLib One reason is that we want to avoid bad guys using our software by simply stealing the DLL that is provided via the program of our customer. 原因之一是我们希望通过简单地窃取通过客户程序提供的DLL来避免恶意软件的使用。 This wouldn't work if parts of the symbols are integrated within the calling software via a static library . 如果部分符号通过静态库集成在调用软件中,则无法使用。 The user of the package shall only be able to use the DLL if he added the symbols of FeatureLib into his application. 软件包的用户只有在将FeatureLib的符号添加到其应用程序后才能使用DLL。

For Linux, I can make this work like a charm,ie the symbol doFeature() is not within libMainLib.so , but I don't succeed on this for Windows. 对于Linux,我可以使其看起来像一个吊饰,即符号doFeature()不在libMainLib.so内,但在Windows上无法成功实现。

CMakeLists.txt : 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 : FeatureLib.h

extern int doFeature(int input);

MainLib.h : MainLib.h

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

FeatureLib.c : FeatureLib.c

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

MainLib.c : 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 : 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;
}

With this, I get the following compilation error: 这样,我得到以下编译错误:

"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

Is this even possible with Windows? Windows甚至可以做到吗? What do I have to do to make it work and how can I verify it other than not linking FeatureLib to MainLibDemo . 除了不将FeatureLib链接到MainLibDemo之外,我必须做些什么才能使其正常工作以及如何进行验证。 Any ideas are very welcome. 任何想法都非常欢迎。

Kind regards, Florian 亲切的问候,弗洛里安

The way you do it under Linux will not work under Windows because dynamic linking works differently here. 在Linux下执行此操作的方法在Windows下将不起作用,因为动态链接在这里的工作方式有所不同。 Here is one strategy that could work. 这是一种可行的策略。

In MainLib.dll code, instead of directly calling doFeature you need to define a global pointer variable of proper function pointer type and use it to call the function. MainLib.dll代码中,需要直接定义适当的函数指针类型的全局指针变量,然后使用它来调用函数,而不是直接调用doFeature This will allow to build MainLib.dll without errors. 这将允许构建MainLib.dll而不会出现错误。

Now you need to set this pointer variable. 现在,您需要设置此指针变量。 One way would be: 一种方法是:

  • Add exported function to MainLib.dll that takes pointers to all functions that the DLL needs from the executable. 将导出的函数添加到MainLib.dll ,该函数采用指向DLL需要可执行文件中所有函数的指针。

  • In FeatureLib.lib code add an initialisation function that the application will need to call before using your DLL which will pass pointers to its peers to the DLL. FeatureLib.lib代码中,添加一个初始化函数,应用程序在使用DLL之前将需要调用该函数,该函数会将指向其对等点的指针传递给DLL。

This is basically the way most programs with plugins use to give the plugins access to their facilities. 基本上,这是大多数带有插件的程序用来使插件访问其设施的方式。

Another way would be to (Warning! I have not tested this specific solution): 另一种方法是(警告!我尚未测试此特定解决方案):

  • Declare the functions in FeatureLib.lib as exported with __declspec(dllexport) . FeatureLib.lib声明通过__declspec(dllexport)导出的功能。 This way they will be exported from executable. 这样,它们将从可执行文件中导出

  • In MainLib.dll before first using the pointers use GetModuleHandle and GetProcAddress to obtain the pointers. MainLib.dll在首次使用指针之前,请先使用GetModuleHandleGetProcAddress获取指针。 It would best be done in some initialisation function for the library. 最好在库的某些初始化函数中完成。 Otherwise you need to take care to avoid race conditions. 否则,您需要注意避免出现竞赛情况。

Hope this will help. 希望这会有所帮助。 Though I do not think your copy protection scheme will work. 虽然我认为您的复制保护方案不起作用。 Andrew Henle is right in his comment: it is not hard to extract the needed code from one executable and include it in another. Andrew Henle的评论是正确的:从一个可执行文件中提取所需的代码并将其包含在另一个可执行文件中并不难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM