Distromate Docs

C++ 接入

C++ SDK 提供了现代 C++ 封装,包含内置的 JSON 解析器和 RSA 签名验证功能

准备工作

  1. 获取 dm_api.dlldm_api.hdm_api.hpp 文件
  2. 需要 OpenSSL 库支持签名验证
  3. 需要 C++17 或更高版本

依赖

  • OpenSSL (libcrypto)
  • C++17 标准库

头文件

#include "dm_api.hpp"

快速开始

#include <iostream>
#include "dm_api.hpp"

int main() {
    // RSA 公钥(PEM 格式)
    const char* publicKey = R"(
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
)";

    try {
        // 创建 API 实例
        DmApi::Api api(publicKey);

        // 1. 检查是否由 Launcher 启动
        if (api.restartAppIfNecessary()) {
            // Launcher 已启动,退出当前进程
            return 0;
        }

        // 2. 连接到 Launcher
        if (!api.connect("\\\\.\\pipe\\distromate_pipe")) {
            std::cerr << "Connection failed: " << api.getLastError() << std::endl;
            return 1;
        }

        // 3. 验证许可证
        auto result = api.verify();
        if (result.has_value()) {
            auto& data = result.value();
            
            // 访问许可证数据
            if (data.contains("license_key")) {
                std::cout << "License: " << data["license_key"].asString() << std::endl;
            }
            if (data.contains("expires_at")) {
                std::cout << "Expires: " << data["expires_at"].asString() << std::endl;
            }
        } else {
            std::cerr << "Verification failed: " << api.getLastError() << std::endl;
            return 1;
        }

        // 4. 通知初始化完成
        if (!api.initiated()) {
            std::cerr << "Failed to notify initiated" << std::endl;
        }

        // 连接会在析构时自动关闭

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

API 参考

DmApi::Api 类

构造函数

Api(const char* publicKeyPem);

参数:

参数类型描述
publicKeyPemconst char*PEM 格式的 RSA 公钥

异常: 如果公钥无效,抛出 std::runtime_error

restartAppIfNecessary

检查程序是否由 Launcher 启动,如果不是则通过 Launcher 重启。

bool restartAppIfNecessary();

返回值:

  • true: 已启动 Launcher,当前进程应退出
  • false: 程序由 Launcher 启动,无需重启

异常: 如果操作失败,抛出 std::runtime_error

connect

连接到 Launcher。

bool connect(const char* pipeName, uint32_t timeoutMs = DM_DEFAULT_TIMEOUT_MS);

参数:

参数类型描述
pipeNameconst char*Pipe 名称,格式: \\.\pipe\<name>
timeoutMsuint32_t超时时间(毫秒),默认 5000ms

返回值: 连接是否成功

close

关闭与 Launcher 的连接。

void close();

isConnected

检查是否已连接。

bool isConnected();

verify

验证许可证。自动生成 nonce 并验证响应签名。

std::optional<JsonValue> verify();

返回值:

  • 成功: 包含许可证数据的 JsonValue
  • 失败: std::nullopt

activate

激活许可证。自动生成 nonce 并验证响应签名。

std::optional<JsonValue> activate();

返回值:verify

initiated

通知 Launcher 程序初始化完成。

bool initiated();

返回值: 操作是否成功

getLastError

获取最后一次错误信息。

std::string getLastError();

getVersion

获取 DLL 版本号。

const char* getVersion();

DmApi::JsonValue 类

内置的轻量级 JSON 值类型。

类型检查

bool isNull();
bool isBool();
bool isNumber();
bool isString();
bool isArray();
bool isObject();

值获取

bool asBool();
double asNumber();
int64_t asInt();
const std::string& asString();
const std::vector<JsonValue>& asArray();
const std::map<std::string, JsonValue>& asObject();

对象访问

bool contains(const std::string& key);
const JsonValue& operator[](const std::string& key);

序列化

std::string toJson(bool sorted = false);

完整示例

#include <iostream>
#include <string>
#include "dm_api.hpp"

const char* PUBLIC_KEY = R"(
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
)";

int main() {
    DmApi::Api api(PUBLIC_KEY);

    // 检查启动方式
    if (api.restartAppIfNecessary()) {
        return 0;  // 退出,让 Launcher 启动程序
    }

    // 连接
    if (!api.connect("\\\\.\\pipe\\distromate_pipe")) {
        std::cerr << "Failed to connect: " << api.getLastError() << std::endl;
        return 1;
    }

    std::cout << "Connected. DLL Version: " << api.getVersion() << std::endl;

    // 验证
    auto data = api.verify();
    if (!data) {
        std::cerr << "Verification failed: " << api.getLastError() << std::endl;
        return 1;
    }

    // 解析许可证信息
    auto& license = data.value();
    
    std::cout << "License verified!" << std::endl;
    
    if (license.contains("user_name")) {
        std::cout << "User: " << license["user_name"].asString() << std::endl;
    }
    
    if (license.contains("product_id")) {
        std::cout << "Product: " << license["product_id"].asString() << std::endl;
    }
    
    if (license.contains("expires_at")) {
        std::cout << "Expires: " << license["expires_at"].asString() << std::endl;
    }

    // 通知完成
    api.initiated();

    // 应用主逻辑...
    std::cout << "Application running..." << std::endl;

    return 0;
}

编译链接

Windows (MSVC)

cl /std:c++17 /EHsc your_app.cpp /I<openssl_include> /link dm_api.lib libcrypto.lib

Windows (MinGW)

g++ -std=c++17 -o your_app.exe your_app.cpp -L. -ldm_api -lcrypto

CMake

cmake_minimum_required(VERSION 3.16)
project(MyApp)

set(CMAKE_CXX_STANDARD 17)

find_package(OpenSSL REQUIRED)

add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE 
    ${CMAKE_CURRENT_SOURCE_DIR}/dm_api.lib
    OpenSSL::Crypto
)

注意事项

  1. C++ SDK 内置了签名验证功能,确保响应数据的安全性
  2. Api 对象的析构函数会自动调用 close()
  3. 所有 API 调用都是同步的
  4. 需要 OpenSSL 支持 RSA 签名验证

On this page