静态 link google protobuf lib 到 dll 库

Statically link google protobuf lib into a dll library

在安装和使用 google protobuf 库 (Install Protobuf On Windows) 的说明页面上指出:

If your project is itself a DLL intended for use by third-party software, we recommend that you do NOT expose protocol buffer objects in your library's public interface, and that you statically link protocol buffers into your library.

我想知道这是如何实现的。据我所知,您可以通过两种方式构建 google protobuf:静态和动态。

如果你动态构建它,你将面临上述问题。如果您静态构建它,那么您将使用 多线程 (/MT) 的 Visual studio 中的代码生成类型。这意味着在我的 dll 库中(它是用 多线程 DLL (/MD) 构建的)你将得到以下 linker 错误:

error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in Emulator.obj

现在有几个问题涉及如何解决这个问题:

但答案很常见,更改您的库以匹配其他库的构建类型。问题是,我不想那样做,我想要一个 DLL。我想静态 link google protobuf,如他们的文档中所述。 我怎样才能做到这一点?

创建一个使用正确库的自定义静态构建的 protobuf 库(您可能希望单独保留默认配置以用于 DLL 的发布版本)。这样,您的 DLL 将在调试版本中使用调试 protobuf 库,在发布版本中使用发布 protobuf 库。

您需要构建自己的 protobuf:

  • 确保你有 CMake
  • protobuf github
  • 下载您的 protobuf 版本源代码
  • 在 VS 开发者命令行中打开此文件夹
  • 运行cmake

    cmake -G "Visual Studio 14" -Dprotobuf_MSVC_STATIC_RUNTIME=ON

您可能想要更改 VS 版本,请查看 cmake 帮助消息以获取正确的生成器名称。

之后 - 一切对您来说都应该很容易。打开生成的解决方案,检查 运行time 库设置,构建 release 和 debug 版本。

并将这些文件(或目录)包含到您的项目链接设置中(对于发布和调试,应该有不同的 lib 文件)。

”。如果您静态构建它,那么您使用的是多线程 (/MT) 的 Visual studio 中的代码生成类型”

不,那是你的错误。

/MT 定义您使用 的 CRT 库。它不是您 制作 的库类型的开关。

正如@MSalters 在回答中指出的那样 the configuration of code generation does not indicate the type of lib that is built, but the type of c++ std lib that is used. In order to modify this on the command line build, it is required that you use the -Dprotobuf_MSVC_STATIC_RUNTIME switch (Credit for advice about this parameter comes from @Ation answer )。为了在生成来自 CMAKE 的 makefile,您必须执行以下操作以进行调试:

cmake -G "NMake Makefiles" ^
-DCMAKE_BUILD_TYPE=Debug  -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ^
-DCMAKE_INSTALL_PREFIX=../../../install/debug ^
../..

或发布:

cmake -G "NMake Makefiles" ^
-DCMAKE_BUILD_TYPE=Release -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ^
-DCMAKE_INSTALL_PREFIX=../../../install/release ^
../..

由以下nmake命令生成的代码将具有多线程DLL (/MD)).

类型的代码生成