端到端实测(/b 脚本按 AecRxBase -> CoreCommand -> cad_mcp_frame 顺序加载)
暴露两个真问题:
1) 版本校验拿到垃圾值,15/16 个工具被误踢
原实现 GetProcAddress(hMod,"acrxGetApiVersion") 转函数指针调用,
和基座自己的 acrxGetApiVersion() 比数值。实测两边返回值是乱的
(1507328 / 2052390912 / 0 交替,其中 1507328=0x170000 才是正确的 23.0),
结果只有第 3 个工具加载成功,其余全被判 SDK 版本不匹配。
改为插件导出数据符号 g_mcpPluginApiVersion=(ARX<<16)|SUB_ARX
(mcp_plugin_api.h 新增 EXPORT_MCP_PLUGIN_VERSION(),每个插件 DLL 调用一次),
基座 GetProcAddress 读内存比对,不涉及调用约定;旧插件没有该符号时只告警按兼容处理。
2) 加载期 AfxMessageBox 会卡住主线程
mcp_ConfigParser 里的几处弹窗全部换成 McpLog:
同时写 %TEMP%\mcp_plugin_load.log 和命令行,并补上每个工具的
[try]/[skip] 明细(dll 是否存在、版本、create/destroy 指针)。
这也是"看起来只加载 3 个工具"的原因——弹窗把主线程挡住了。
实测结果(R230,自动化烟测):
端口 127.0.0.1:8080 6 s 内监听
tools/list 返回 18 个工具(2 lisp_inline + 16 c++_dll)
5 KB 大请求 -32601,证明整包被读完(旧实现会截断)
tools/call get_layers 真正执行插件,返回 {"count":1,"items":[{"name":"0",...}]}
加载日志 16 个 c++_dll 全部 [try] 成功,0 个 [skip]
另外把配置文件加入构建部署:copyarx.exe 能拷任意文件,照 set_debug_post_build 的写法
再加一条 POST_BUILD,把 cad-mcp-frame.json 也拷到部署目录(ZWCAD 走 zw_output_path.json)。
不部署的话 frame 起来后 LoadAndRegister 找不到配置会直接自关。
验证:R230 与 Z2026 的 frame + plugins 均编译通过并部署;R230 已做上述端到端实测。
69 lines
2.2 KiB
CMake
69 lines
2.2 KiB
CMake
cmake_minimum_required(VERSION 3.16)
|
||
|
||
project(CadMcpFrame)
|
||
|
||
set(SOURCES
|
||
"cad_mcp_frame.cpp"
|
||
"command.cpp"
|
||
"mcp_server.cpp"
|
||
"mcp_tool.cpp"
|
||
"mcp_ConfigParser.cpp"
|
||
"mcp_utils.cpp"
|
||
"StdAfx.cpp"
|
||
"cad_mcp_frame.rc"
|
||
)
|
||
add_def_file_name(SOURCES "cad_mcp_frame")
|
||
|
||
add_library(CadMcpFrame SHARED ${SOURCES})
|
||
|
||
target_precompile_headers(CadMcpFrame PRIVATE StdAfx.h)
|
||
|
||
target_set_name_and_suffix(CadMcpFrame "cad_mcp_frame" ".arx")
|
||
|
||
target_link_objectarx(CadMcpFrame CADMCPFRAME_EXPORT)
|
||
|
||
# mcp_plugin_api.h 已上移到 SourceCode/Code2026/inc(frame 与 plugins 共用),
|
||
# 由 target_link_objectarx 引入的 ShsGlobalIncludes 自动可见
|
||
|
||
target_compile_definitions(CadMcpFrame PRIVATE
|
||
AECRXBASE_EXPORT
|
||
EARTHWORM_EXPORT
|
||
)
|
||
|
||
# 原工程用 SUB_ARX 表示 SDK 子版本(打印版本号时用),code2026 的
|
||
# target_link_objectarx 只注入 ARX,这里补上;中望没有子版本,给 0
|
||
if (IS_ZWCAD)
|
||
target_compile_definitions(CadMcpFrame PRIVATE SUB_ARX=0)
|
||
else()
|
||
target_compile_definitions(CadMcpFrame PRIVATE SUB_ARX=${CAD_SDK_SUBVERSION})
|
||
endif()
|
||
|
||
# nlohmann/json 与 ghc::filesystem 都是单头,放在 SourceCode/dep_inc 下,
|
||
# 由 target_link_objectarx 把 DEP_INC_ROOT 加进 include 路径
|
||
target_link_libraries(CadMcpFrame PRIVATE
|
||
AecRxBase
|
||
)
|
||
|
||
set_debug_post_build(CadMcpFrame "cad_mcp_frame" ".arx")
|
||
|
||
# 配置文件也要部署:copyarx.exe 会把任意文件按 sh_output_path.json 的 desc_path 拷过去,
|
||
# 但 set_debug_post_build 固定用 $<TARGET_FILE:...>,拷不了额外文件,所以照它的写法再来一条。
|
||
# 不部署的话,frame 起来后 LoadAndRegister 找不到配置会直接自关。
|
||
if (IS_ZWCAD)
|
||
set(MCP_OUTPUT_JSON "zw_output_path.json")
|
||
else()
|
||
set(MCP_OUTPUT_JSON "sh_output_path.json")
|
||
endif()
|
||
|
||
add_custom_command(
|
||
TARGET CadMcpFrame
|
||
POST_BUILD
|
||
COMMAND "$<$<CONFIG:Debug>:${CMAKE_SOURCE_DIR}/copyarx.exe>"
|
||
"$<$<CONFIG:Debug>:CMAKE>"
|
||
"$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/cad-mcp-frame.json>"
|
||
"$<$<CONFIG:Debug>:${GENERATE_DIR_TAG}>"
|
||
"$<$<CONFIG:Debug>:${CMAKE_SOURCE_DIR}/${MCP_OUTPUT_JSON}>"
|
||
COMMENT "正在部署 cad_mcp_frame 的配置文件..."
|
||
VERBATIM
|
||
)
|