我是否需要使用DLL分发头文件和lib文件?

时间:2016-05-17 17:31:35

标签: c++ visual-c++ dll shared-libraries

我正在为客户更新DLL,并且由于公司政治等原因,我的公司决定不再与客户共享源代码。

以前。我假设他们拥有所有源代码并将其作为VC ++ 6项目导入。现在他们将不得不链接到预编译的DLL。我想,至少,我需要使用DLL分发*.lib文件,以便可以定义DLL入口点。但是,我是否还需要分发头文件?

如果我不能分发它,客户将如何将DLL导入其代码?

4 个答案:

答案 0 :(得分:13)

是的,您需要将标题与.lib和.dll

一起分发

为什么?

至少有两个原因:

  • 因为C ++需要知道库中函数的返回类型和参数(粗略地说,大多数编译器使用name mangling,将C ++函数签名映射到库入口点)。
  • 因为如果您的库使用类,C ++编译器需要知道它们的布局以在库客户机中生成代码(例如,要在堆栈上放置多少字节以进行参数传递)。

附加说明: 如果您因为想要隐藏标题中的实施细节而问这个问题,可以考虑{{3 }}。但这需要对代码进行一些重构,并且还会对性能产生一些影响,因此请仔细考虑

答案 1 :(得分:5)

  

但是,我是否还需要分发头文件?

是。否则,您的客户必须先手动声明这些功能,然后才能使用它们。你可以想象,这将是非常容易出错和调试的噩梦。

答案 2 :(得分:2)

除了其他人对头/ LIB文件的解释外,这里有不同的视角。

客户无论如何都能够使用Dependency Walker等基本工具对DLL进行逆向工程,以找出DLL正在使用的系统DLL,DLL使用的函数(例如AdvApi32.DLL中的某些函数) )。

如果您希望您的DLL 隐藏,您的DLL必须:

  • 动态加载所有自定义DLL(如果不可能的话,无论如何都要做下一件事)
  • 致电GetProcAddress,了解您要致电的所有功能(GetProcessToken来自ADVAPI32.DLL

这样,至少依赖性walker(没有跟踪)无法找到正在使用的函数(或DLL)。您可以按顺序加载系统DLL的功能,而不是按名称加载,因此在DLL中通过文本搜索进行逆向工程变得更加困难。

调试器仍然可以调试你的DLL(以及其他工具)并对其进行反向工程。您需要找到防止调试DLL的技术。例如,最基本的API是IsDebuggerPresent。其他先进的方法是可用的。

为什么我说这一切?好吧,如果您打算提供标头/ DLL,客户仍然可以找到导出的功能并使用它。作为DLL提供者,您还必须提供编程元素。如果你必须隐藏,那么完全隐藏它。

答案 3 :(得分:0)

您可以使用的一种替代方法是仅传递DLL,并让客户使用 LoadLibrary() + GetProcAddress()动态加载它 。尽管您仍然需要让客户知道DLL中功能的签名。

此处有更详细的示例:

Dynamically load a function from a DLL