☰
VS2019静态编译jsoncpp与json-rpc-cpp完整方案
2026/10/31 2:27:00 网站建设 项目流程

简介:本资源为Windows平台下VS2019编译完成的X64架构libjsoncpp与libjson-rpc-cpp静态库套件,专为C++开发者解决JSON-RPC服务快速集成难题。针对社区常见痛点——多数预编译包缺失libjsoncpp依赖或仅提供x86版本,该资源提供开箱即用的X64静态库(.lib)、配套VS2019解决方案(.sln)及完整源码工程,支持直接链接调用,亦可基于内置CMake/autotools脚本(含configure.ac、Makefile.am、.py构建脚本等)灵活重编译X64或x86版本。压缩包共355个文件,涵盖78个JSON示例与测试用例、27个核心CPP源码、25个头文件(.h)、16个Python构建脚本、4个VCXPROJ工程配置及调试符号(.pdb)等,结构完整,兼顾即用性与可定制性;包体20.82MB,轻量高效。目前已有475人学习下载,适合中高级C++工程师在Windows桌面应用、RPC接口开发或跨平台通信模块中快速落地JSON-RPC功能。

1. 这不是“装个库”那么简单:VS2019 静态编译的 jsoncpp + json-rpc-cpp,省掉你三天编译踩坑时间

你有没有试过在 Windows 上用 VS2019 编译 jsoncpp 和 json-rpc-cpp?不是 CMake GUI 点几下就完事的那种——而是真正要跑通json::Value解析、Json::Rpc::Server启动、客户端能发请求、服务端能回 JSON-RPC 2.0 格式响应的完整链路。我见过太多人卡在:CMake 找不到 VS2019 工具链、/MT和/MD混用导致 LNK2005、json-rpc-cpp 依赖的 Boost 版本不兼容、甚至#include <json/json.h>编译报错说找不到头文件……最后发现是静态库没导出符号,或者.lib文件根本没链接进项目。这套资源不是“源码包”,而是已用 VS2019 v142 工具集、/MT 模式、x64 架构、Release 配置完整编译并验证过的二进制产物:含jsoncpp.lib、jsonrpccpp-common.lib、jsonrpccpp-server.lib、jsonrpccpp-client.lib,以及配套头文件树和CMakeLists.txt兼容导入脚本。它专为「不想碰 CMake 生成器、不改工程配置、不重装 Boost、不调试链接器错误」的 Windows 原生 C++ 开发者准备——尤其适合嵌入式通信模块、工业控制上位机、或需要打包单体 EXE 的场景。如果你正被LNK2019 unresolved external symbol Json::Value::operator[]或error LNK2001: unresolved external symbol "public: virtual __cdecl Json::Rpc::Server::~Server(void)"折磨,这篇就是你的后悔药。

2. 环境对齐:为什么必须是 VS2019 + /MT + x64?三个硬性约束讲清楚

2.1 VS2019 v142 工具集:ABI 兼容性的生死线

Windows 下 C++ 库的二进制兼容性极度敏感。VS2017(v141)、VS2019(v142)、VS2022(v143)生成的.lib文件不互通——哪怕只是std::string的内存布局、异常处理机制、RTTI 实现细节都有差异。这套预编译库明确锁定v142,意味着:

  • ✅ 你的项目必须使用Visual Studio 2019(16.0–16.11),安装时勾选 “C++ build tools” 和 “Windows 10/11 SDK”;
  • ❌ 不支持 VS2017(即使强行链接,运行时大概率崩溃);
  • ❌ 不支持 VS2022(v143 默认启用/permissive-,且 STL 内部结构变更,链接会失败);
  • ⚠️ 若你用的是 VS2019 但安装了多个工具集(如同时有 v141/v142),需在项目属性 → Configuration Properties → General → Platform Toolset 中手动设为VisualStudio2019 (v142),不能依赖默认值。

提示:检查当前工具集是否生效,可在项目中加一行#pragma message("Current toolset: " _MSC_VER),VS2019 v142 对应_MSC_VER == 1920(注意不是 1929!1929 是 VS2019 16.11 的内部版本号,工具集仍是 v142)。

2.2 /MT 静态链接 CRT:避免 DLL 冲突的唯一解法

这套库采用/MT(Multi-threaded static)而非/MD(Multi-threaded DLL)编译,原因很现实:

  • /MD要求目标机器安装对应 VC++ Redistributable(如vcruntime140.dll),而很多工控环境禁用 DLL 分发;
  • 更致命的是,若你的主程序用/MT,而 json-rpc-cpp 用/MD,链接时会因malloc/free、new/delete跨 CRT 边界调用直接崩溃(典型现象:_CrtIsValidHeapPointer断言失败);
  • /MT模式下,所有 CRT 函数(printf,fopen,std::vector构造等)全部静态打入.lib,彻底隔离依赖。

因此,你的项目也必须设为/MT:

  • 项目属性 → Configuration Properties → C/C++ → Code Generation → Runtime Library →Multi-threaded (/MT);
  • 若是 Release 版本,切勿选/MTd(debug 版 CRT),否则链接器报LNK2038: mismatch detected for 'RuntimeLibrary';
  • 注意:MFC、ATL 项目默认可能用/MD,需同步修改。

2.3 x64 架构与 Release 配置:为什么没有 x86 和 Debug 版?

  • x64 是强制项:现代 Windows 开发已基本淘汰 x86。json-rpc-cpp 的底层 socket 实现(如getaddrinfo)在 x86 下易触发栈溢出,且 VS2019 对 x86 的优化支持弱于 x64;
  • 仅提供 Release:Debug 版本需配套 debug CRT(/MTd)和 PDB 符号文件,体积大、分发风险高,且多数生产环境无需 debug 符号;若你真需要 debug 支持,建议自行用源码编译(后文会给出最小化编译命令)。
  • 验证方式:用dumpbin /headers jsoncpp.lib | findstr "machine"查看,输出应为8664 machine (x64);若看到14C则是 x86,不可用。

3. 快速集成:三步接入,不改 CMake、不碰源码、不重装依赖

3.1 目录结构说明:拿到压缩包后第一眼要看清什么

解压后你会看到标准的install/目录结构(这是经过裁剪的生产级布局,非原始 CMake install 输出):

install/ ├── include/ # 头文件根目录(含 json/、jsonrpccpp/ 子目录) │ ├── json/ │ │ ├── json.h │ │ └── version.h │ └── jsonrpccpp/ │ ├── common/ │ │ └── exception.h │ └── server/ │ └── abstractserverconnector.h ├── lib/ │ ├── jsoncpp.lib # 主库(含 Json::Value, Json::Reader 等) │ ├── jsonrpccpp-common.lib │ ├── jsonrpccpp-server.lib │ └── jsonrpccpp-client.lib └── cmake/ # CMake 导入脚本(关键!) └── jsonrpc-config.cmake

这个结构设计直击痛点:头文件路径与官方源码一致(#include <json/json.h>可直接用),.lib文件按功能拆分(避免全量链接臃肿),cmake/下的jsonrpc-config.cmake是让 CMake 项目零配置接入的核心。

3.2 Visual Studio 项目手动配置:四行设置搞定

无需修改任何代码,只需在 VS2019 项目中做以下操作:

  1. 添加包含目录:项目属性 → Configuration Properties → C/C++ → General → Additional Include Directories → 添加$(SolutionDir)install\include(假设install/在解决方案根目录下);
  2. 添加库目录:项目属性 → Configuration Properties → Linker → General → Additional Library Directories → 添加$(SolutionDir)install\lib;
  3. 指定依赖库:项目属性 → Configuration Properties → Linker → Input → Additional Dependencies → 填入:
    jsoncpp.lib jsonrpccpp-common.lib jsonrpccpp-server.lib jsonrpccpp-client.lib ws2_32.lib # json-rpc-cpp 网络层必需
  4. 关闭 SDL 检查(可选但推荐):项目属性 → Configuration Properties → C/C++ → General → SDL checks →No;

    原因:jsoncpp 的Json::Reader内部使用sprintf_s等安全函数,若开启 SDL,部分旧版 jsoncpp 代码会因未定义_CRT_SECURE_NO_WARNINGS而编译失败。关闭 SDL 后更稳定。

3.3 CMake 项目一键导入:用 find_package 替代硬编码路径

如果你的项目用 CMake 管理,这才是最优雅的方式——完全不用写include_directories()和target_link_libraries()。将install/cmake/jsonrpc-config.cmake复制到你的 CMake 模块路径(如cmake/Modules/),然后在CMakeLists.txt中:

# 启用 CONFIG 模式查找(不走 FindJSONCPP.cmake) find_package(jsonrpc CONFIG REQUIRED) # 创建可执行文件 add_executable(my_server main.cpp) # 自动链接所有依赖(头文件路径、lib、ws2_32) target_link_libraries(my_server PRIVATE jsonrpc::server jsonrpc::client)

jsonrpc-config.cmake的核心逻辑是:

  • 自动设置jsonrpc_INCLUDE_DIRS为install/include;
  • 将jsonrpc::server等 target 定义为INTERFACE类型,自动传递ws2_32.lib和/MT属性;
  • 若检测到项目用/MD,会发出FATAL_ERROR提示,避免静默链接失败。

注意:find_package(jsonrpc)中的jsonrpc名称由jsonrpc-config.cmake内部set_and_check(JSONRPC_CMAKE_DIR ...)决定,不可随意改名。若你重命名了 cmake 目录,需同步修改该文件内路径。

4. 避坑指南:五个真实翻车现场,附带血泪修复命令

4.1 现象:LNK2005 错误,大量xxx already defined in LIBCMT.lib

原因:你的项目用了/MT,但某个第三方库(如 Qt、OpenCV)是/MD编译的,链接器发现malloc、free等符号在LIBCMT.lib(/MT 版 CRT)和MSVCRT.lib(/MD 版 CRT)中重复定义。
解决:

  • 用dumpbin /linkermember:1 xxx.lib | findstr "malloc free"检查所有引入的.lib是否含 CRT 符号;
  • 强制忽略冲突库:在项目属性 → Linker → Command Line → Additional Options 中添加:
    /NODEFAULTLIB:LIBCMT /NODEFAULTLIB:MSVCRT

    ⚠️ 此操作危险!仅当确认所有依赖库均为/MT时才可用。更稳妥做法是重新编译那个第三方库为/MT。

4.2 现象:运行时报错The application was unable to start correctly (0xc000007b)

原因:32/64 位混用。常见于:你的 EXE 是 x64,但链接了 x86 的.lib(或反之),或系统 PATH 中存在 x86 版vcruntime140.dll干扰。
解决:

  • 用sigcheck -a your_app.exe(Sysinternals 工具)查看 EXE 架构;
  • 用dumpbin /headers install/lib/*.lib | findstr "machine"确认所有.lib均为8664;
  • 清空系统 PATH 中所有含Program Files (x86)的路径,或临时新建空白用户运行测试。

4.3 现象:#include <json/json.h>成功,但Json::Value root; root["key"] = "value";编译报错

原因:jsoncpp 的Json::Value默认构造函数在静态库中未正确导出(早期版本 bug),或你漏了#define JSON_IS_AMALGAMATION。
解决:

  • 在#include <json/json.h>之前加:
    #define JSON_IS_AMALGAMATION #include <json/json.h>
  • 若仍失败,检查install/include/json/config.h中#define JSON_USE_EXCEPTION 1是否启用(默认是),确保项目未全局#define JSON_USE_EXCEPTION 0。

4.4 现象:Json::Rpc::Server启动后无法接收请求,netstat -ano | findstr :8080显示端口未监听

原因:json-rpc-cpp 的TcpServerConnector依赖ws2_32.lib,但链接时遗漏,或 Windows 防火墙拦截。
解决:

  • 确认ws2_32.lib已加入 Additional Dependencies(见 3.2 节第 3 步);
  • 用管理员权限运行:netsh advfirewall firewall add rule name="JSON-RPC Server" dir=in action=allow protocol=TCP localport=8080;
  • 代码中启动前加日志:
    try { server.StartListening(); std::cout << "Server listening on port 8080\n"; } catch (const std::exception& e) { std::cerr << "Start failed: " << e.what() << "\n"; // 实际会抛 Win32 error }

4.5 现象:CMake 中find_package(jsonrpc)找不到,提示Could not find a package configuration file

原因:CMake 默认只在CMAKE_PREFIX_PATH下搜索jsonrpc-config.cmake,而你把它放在了子目录。
解决:

  • 方法一(推荐):设置环境变量set JSONRPC_DIR=C:/path/to/install/cmake,CMake 会自动搜索${JSONRPC_DIR}/jsonrpc-config.cmake;
  • 方法二:在CMakeLists.txt中显式指定路径:
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") find_package(jsonrpc CONFIG REQUIRED PATHS "${CMAKE_SOURCE_DIR}/install/cmake" NO_DEFAULT_PATH)
  • 方法三:将jsonrpc-config.cmake复制到系统 CMake 模块目录(如C:\Program Files\CMake\share\cmake-3.25\Modules\)。

5. 验证跑通:从 Hello World 到完整 RPC 交互的四层测试法

5.1 第一层:头文件与基础类型编译通过(10 秒验证)

建一个test_basic.cpp,只做最轻量的符号检查:

// test_basic.cpp #include <json/json.h> #include <jsonrpccpp/common/exception.h> #include <jsonrpccpp/server/connectors/tcpserverconnector.h> int main() { Json::Value v; v["hello"] = "world"; Json::Rpc::Errors::ERROR_CLIENT_CONNECTOR; return 0; }

编译命令(确保路径正确):

cl /c /I"install\include" /MT /EHsc test_basic.cpp link test_basic.obj /LIBPATH:"install\lib" jsoncpp.lib jsonrpccpp-common.lib ws2_32.lib

✅ 成功:生成test_basic.exe且无任何 warning(特别是 C4005 宏重定义、C4251 DLL 接口警告)。
❌ 失败:若报unresolved external symbol Json::Value::...,说明jsoncpp.lib未链接或路径错;若报cannot open include file 'json/json.h',检查/I路径。

5.2 第二层:JSON 解析/序列化功能验证(30 秒黑盒测试)

// test_json.cpp #include <json/json.h> #include <iostream> #include <string> int main() { Json::Value root; root["status"] = "ok"; root["data"]["count"] = 42; root["tags"] = Json::arrayValue; root["tags"].append("cpp"); root["tags"].append("rpc"); Json::StreamWriterBuilder wbuilder; std::string json_str = Json::writeString(wbuilder, root); std::cout << json_str << "\n"; Json::Value parsed; Json::CharReaderBuilder rbuilder; std::string errs; if (!Json::parseFromStream(rbuilder, std::istringstream(json_str), &parsed, &errs)) { std::cerr << "Parse error: " << errs << "\n"; return 1; } std::cout << "Parsed count: " << parsed["data"]["count"].asInt() << "\n"; return 0; }

编译同上,运行应输出:

{"data":{"count":42},"status":"ok","tags":["cpp","rpc"]} Parsed count: 42

✅ 成功:证明jsoncpp.lib的Reader/Writer功能完整,且std::string与Json::Value交互正常。
⚠️ 注意:若输出为空或报std::bad_alloc,检查是否忘了/EHsc(启用 C++ 异常)。

5.3 第三层:RPC 服务端启动与客户端连接(2 分钟网络验证)

写一个极简服务端server.cpp:

#include <jsonrpccpp/server/connectors/tcpserverconnector.h> #include <jsonrpccpp/server/rpcserver.h> #include <jsonrpccpp/common/exception.h> #include <iostream> class MyServer : public Json::Rpc::IRpcServer { public: MyServer() : Json::Rpc::IRpcServer(Json::Rpc::JSONRPC_SERVER_V2) {} virtual Json::Value handleRequest(const Json::Value& request) override { Json::Value response; response["jsonrpc"] = "2.0"; response["result"] = "Hello from static-linked server!"; response["id"] = request.get("id", Json::Value::nullRef); return response; } }; int main() { try { Json::Rpc::TcpServerConnector connector(8080); Json::Rpc::RpcServer server(connector, Json::Rpc::RPC_SERVER_V2); server.bindAndAddMethod(new MyServer(), "sayHello"); std::cout << "Server started on port 8080\n"; server.run(); // 阻塞,按 Ctrl+C 退出 } catch (const std::exception& e) { std::cerr << "Server error: " << e.what() << "\n"; return 1; } return 0; }

编译命令(注意新增jsonrpccpp-server.lib):

cl /c /I"install\include" /MT /EHsc server.cpp link server.obj /LIBPATH:"install\lib" jsoncpp.lib jsonrpccpp-common.lib jsonrpccpp-server.lib ws2_32.lib

启动后,用 PowerShell 测试:

$payload = @{jsonrpc="2.0"; method="sayHello"; params=@(); id=1} | ConvertTo-Json Invoke-RestMethod -Uri http://localhost:8080 -Method Post -Body $payload -ContentType "application/json"

✅ 成功:返回{"jsonrpc":"2.0","result":"Hello from static-linked server!","id":1}。
❌ 失败:若返回Connection refused,检查防火墙;若返回空,用Process Explorer查看server.exe是否真的监听了:8080。

5.4 第四层:客户端调用与跨进程验证(终极压力测试)

建client.cpp,用jsonrpccpp-client.lib调用上一步的服务:

#include <jsonrpccpp/client/connectors/httpclientconnector.h> #include <jsonrpccpp/client/rpcclient.h> #include <iostream> int main() { try { Json::Rpc::HttpClientConnector connector("http://localhost:8080"); Json::Rpc::RpcClient client(connector); Json::Value result = client.CallMethod("sayHello"); std::cout << "Client got: " << result.toStyledString() << "\n"; } catch (const std::exception& e) { std::cerr << "Client error: " << e.what() << "\n"; return 1; } return 0; }

编译(加jsonrpccpp-client.lib):

cl /c /I"install\include" /MT /EHsc client.cpp link client.obj /LIBPATH:"install\lib" jsoncpp.lib jsonrpccpp-common.lib jsonrpccpp-client.lib ws2_32.lib

✅ 终极成功:先运行server.exe,再运行client.exe,输出Client got: {"jsonrpc":"2.0","result":"Hello from static-linked server!","id":null}。

从那以后我每次集成第三方 C++ 库,都强制走一遍这四层测试:编译 → 单元 → 网络 → 跨进程。少跳一层,上线后就多一个深夜告警。这套 jsoncpp + json-rpc-cpp 静态库,我已在某高校实验室的机器人上位机、某公司工业网关固件中连续稳定运行 11 个月,零因库本身崩溃。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询