#pragma once #include #include class mcp_Tool_Utility { public: static std::wstring utf8ToWString(const std::string &utf8Str) { if (utf8Str.empty()) return std::wstring(); // 第一次调用获取需要的宽字符缓冲区大小 int sizeNeeded = ::MultiByteToWideChar(CP_UTF8, 0, &utf8Str[0], (int)utf8Str.size(), NULL, 0); std::wstring wstrTo(sizeNeeded, 0); // 第二次调用真正进行转换 ::MultiByteToWideChar(CP_UTF8, 0, &utf8Str[0], (int)utf8Str.size(), &wstrTo[0], sizeNeeded); return wstrTo; } static std::string WStringToUtf8(const std::wstring &wstr) { if (wstr.empty()) return std::string(); // 第一次调用获取需要的 UTF-8 缓冲区大小 int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); std::string strTo(sizeNeeded, 0); // 第二次调用真正进行转换 WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], sizeNeeded, NULL, NULL); return strTo; } // 1. 纯文本响应 static nlohmann::json make_text_result(const std::wstring &_text) { std::string text = WStringToUtf8(_text); return { { "result", { { "content", { { { "type", "text" }, { "text", text } } } } } } }; } // 2. 图片响应 (传入 base64 编码的图片数据) static nlohmann::json make_image_result(const std::string &base64Data , const std::string &mimeType = "image/png") { return { { "result", { { "content", { { { "type", "image" }, { "data", base64Data }, { "mimeType", mimeType } } } } } } }; } // 3. 图文混合响应 (文字汇报结果 + 附带 CAD 视口截图) static nlohmann::json make_mixed_result(const std::wstring &_text , const std::string &base64Data , const std::string &mimeType = "image/png") { std::string text = WStringToUtf8(_text); return { { "result", { { "content", { { { "type", "text" }, { "text", text } }, { { "type", "image" }, { "data", base64Data }, { "mimeType", mimeType } } } } } } }; } static nlohmann::json make_error(int code, const std::wstring &_message) { std::string message = WStringToUtf8(_message); return { { "error",{ { "code", code }, { "message", message } } } }; } }; class mcp_Tool { protected: nlohmann::json m_config; std::string m_abiBuffer; // 存在于对象实例自己的堆内存中,确保指针生命周期安全 public: virtual ~mcp_Tool() = default; void SetConfig(const nlohmann::json &config) { m_config = config; } // 兜底三剑客:当 JSON 中不写这些字段时,才调用这里(均可选重载) virtual std::string private_name() const { return "unnamed_tool"; } virtual std::string private_description() const { return ""; } virtual nlohmann::json private_input_schema() const { return nlohmann::json::object(); } // 统一由框架接管 Name 的获取 (供路由字典 mcp_Tools::Register 调用) virtual std::string GetName() const final { return m_config.value("name", private_name()); } // 统一由框架接管 ToLLM 组装 virtual nlohmann::json ToLLM() const final { nlohmann::json tool; tool["name"] = GetName(); std::string desc = m_config.value("description", ""); tool["description"] = desc.empty() ? private_description() : desc; if (m_config.contains("inputSchema") && !m_config["inputSchema"].empty()) { tool["inputSchema"] = m_config["inputSchema"]; } else { tool["inputSchema"] = private_input_schema(); } return tool; } // 整个类唯一一个纯虚函数:全心全意干活! virtual nlohmann::json Execute(const nlohmann::json &args) = 0; // 安全配置注入 virtual void SetConfigAbiSafe(const char* config_json_str) { // 在 DLL 内部的安全环境中完成字符串到 JSON 的反序列化 m_config = nlohmann::json::parse(config_json_str); } // 安全执行路由 virtual const char* ExecuteAbiSafe(const char* args_json_str) { // 1. 在 DLL 的上下文中,将传入的 C 字符串转为 JSON nlohmann::json args = nlohmann::json::parse(args_json_str); // 2. 调用真实的业务逻辑 nlohmann::json result = Execute(args); // 3. 将结果序列化为字符串,存入属于该 DLL 的内存缓冲区 m_abiBuffer = result.dump(); // 4. 返回安全的 C 指针 return m_abiBuffer.c_str(); } }; #define EXPORT_MCP_TOOL(ToolClass, FactoryName) \ extern "C" __declspec(dllexport) mcp_Tool* FactoryName() \ { \ return new ToolClass(); \ } \ extern "C" __declspec(dllexport) void Destroy_##FactoryName(mcp_Tool* pTool) \ { \ delete pTool; \ }