【问题标题】:Statically link google protobuf lib into a dll library将 google protobuf lib 静态链接到 dll 库中
【发布时间】:2018-06-02 16:09:35
【问题描述】:

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

如果您的项目本身是一个供第三方软件使用的 DLL,我们建议您不要在库的公共接口中公开协议缓冲区对象,并且您将协议缓冲区静态链接到您的库中强>。

我想知道如何做到这一点。据我所知,您可以通过两种方式构建 google protobuf:静态和动态。

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

错误 LNK2038:检测到“RuntimeLibrary”不匹配:值“MTd_StaticDebug”与 Emulator.obj 中的值“MDd_DynamicDebug”不匹配

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

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

【问题讨论】:

    标签: c++ dll linker protocol-buffers linker-errors


    【解决方案1】:

    正如@MSalters 所指出的,在答案here 中,代码生成的配置并不表示构建的lib 的类型,而是表示使用的c++ std lib 的类型。为了在命令行构建中修改它,需要使用-Dprotobuf_MSVC_STATIC_RUNTIME 开关(有关此参数的建议来自@Ation 答案here)。为了将构建设置为使用多线程 DLL (/MD)) 专门用于 google protobuf,从 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)) 类型的代码生成

    【讨论】:

    • 不知道的可以找windows上构建prtobuf的步骤here
    【解决方案2】:

    您需要构建自己的 protobuf:

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

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

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

    在那之后 - 一切对你来说应该很容易。打开生成的解决方案,检查运行时库设置,构建发布和调试版本。

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

    【讨论】:

    • 所以我开始朝那个方向前进。不过,如果可能的话,我希望从命令行执行此操作。
    • devenv protobuf.sln /build [发布|调试] /project protoc
    • 请记住,默认情况下会生成 win32(x86) 项目。如果您需要 x64 将“Win64”添加到生成器(Visual Studio 14 Win64)
    • 我根据您对参数protobuf_MSVC_STATIC_RUNTIME 的建议找到了命令行的答案。你能告诉我你在哪里找到这方面的信息吗?我很想知道。
    • 来自 CMakeLists.txt 本身:(。也请为未来的访问者标记正确的答案(即使是您自己的回复)。
    【解决方案3】:

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

    不,那是你的错误。

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

    【讨论】:

    • 好的,进展不错,有没有办法从命令行设置这个参数?
    • @FantasticMrFox:哪个参数?显然/MT等是命令行参数。
    • 所以为了设置代码生成类型,它必须在生成makefile的过程中完成。幸运的是,谷歌想到了这一点并添加了protobuf_MSVC_STATIC_RUNTIME 开关。我在回答中详细说明了这一点。
    【解决方案4】:

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

    【讨论】:

    • 这太模糊了。 right 库是什么?能详细解释一下吗?
    猜你喜欢
    • 1970-01-01
    • 2015-08-24
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    相关资源
    最近更新 更多