我需要分发一个头文件和一个带有 DLL 的 lib 文件吗?

Do I need to distribute a header file and a lib file with a DLL?

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

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

如果我可以不分发它,客户将如何将 DLL 导入到他们的代码中?

However, do I also need to distribute the header file?

是的。否则,您的客户将不得不自己手动声明这些功能,然后才能使用它。正如您所想象的那样,这将非常容易出错并且是调试的噩梦。

是的,您需要将 header 连同您的 .lib 和 .dll

为什么?

至少有两个原因:

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

补充说明:如果你问这个问题是因为你想对 header 隐藏实现细节,你可以考虑pimpl idiom。但这需要对您的代码进行一些重构,并且还会对性能产生一些影响,因此请仔细考虑

除了其他人对header/LIB文件的解释外,这里还有不同的观点。

客户无论如何都可以使用 Dependency Walker 等基本工具对 DLL 进行逆向工程,以查明您的 DLL 使用的是哪些系统 DLL,您的 DLL 使用了哪些函数(例如来自 AdvApi32.DLL).

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

  • 动态加载所有自定义 DLL(如果不可能,无论如何做下一步)
  • 在您要调用的所有函数上调用 GetProcAddress(例如 ADVAPI32.DLL 中的 GetProcessToken

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

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

我为什么要说这些?好吧,如果您打算 交付 header/DLL,客户仍然能够找到导出的函数并使用它。作为 DLL 提供者,您还必须为其提供编程元素。非要躲就躲得彻底

您可以使用的一种替代方法是仅传递 DLL 并让客户使用 LoadLibrary() + GetProcAddress()。尽管您仍然需要让您的客户知道 DLL 中函数的签名。

这里有更详细的示例:

Dynamically load a function from a DLL