静态 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
现在有几个问题涉及如何解决这个问题:
- error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700' in CppFile1.obj
- Mismatch Detected for 'RuntimeLibrary'
- (非常相似)
但答案很常见,更改您的库以匹配其他库的构建类型。问题是,我不想那样做,我想要一个 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)).
类型的代码生成
在安装和使用 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
现在有几个问题涉及如何解决这个问题:
- error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700' in CppFile1.obj
- Mismatch Detected for 'RuntimeLibrary'
- (非常相似)
但答案很常见,更改您的库以匹配其他库的构建类型。问题是,我不想那样做,我想要一个 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 在回答中指出的那样 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 -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)).