You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拦截cncapi.dll中CncRunSingleLine调用后程序崩溃问题求助

问题描述

我正在修改名为EdingCNC的应用程序,该程序依赖动态链接库cncapi.dll实现核心功能。我的目标是拦截该DLL中的CncRunSingleLine函数调用,必要时修改行为后转发至原函数,其余函数通过#pragma comment(linker, "/export:...=...,@...")直接转发。

该函数在cncapi.dll中的签名为:

CNC_RC EXP2DF __stdcall CncRunSingleLine(char *text);

实现方案(代理DLL)

为拦截该函数,我创建了一个同名导出的代理DLL,捕获CncRunSingleLine的调用,执行额外逻辑后调用原cncapi.dll中的函数。当前实现代码如下:

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
//
HINSTANCE gDllhInstance = NULL; // 当前DLL句柄的全局存储

BOOL ProcessAttach();
BOOL ProcessDetach();

BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, PVOID pvReserved)
{
    UNREFERENCED_PARAMETER(pvReserved);
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        gDllhInstance = hInstDLL;
        return ProcessAttach();
    case DLL_PROCESS_DETACH:
        return ProcessDetach();
    }
    return TRUE;
}

BOOL ProcessAttach()
{
    return TRUE;
}

BOOL ProcessDetach()
{
    return TRUE;
}

// 定义原函数的函数指针类型

typedef enum CNC_RC
{
    CNC_RC_OK = 0,       /* 成功 */
    CNC_RC_BUF_EMPTY = 1,       /* 缓冲区为空 */
    CNC_RC_TRACE = 2,       /* 跟踪信息 */
    CNC_RC_USER_INFO = 3,       /* 用户消息 */
    CNC_RC_SHUTDOWN = 4,       /* CMD_CLOSE后处理请求返回 */
    CNC_RC_EXISTING = 5,       /* 共享内存已存在 */
    CNC_RC_ALREADY_RUNS = 6,       /* 服务端已在运行 */
    CNC_RC_ALREADY_CONNECTED = 7,  /* 已调用CncConnectServer() */
    CNC_RC_ERR = -1,       /* 无数据在FIFO中 */
    CNC_RC_ERR_PAR = -2,       /* 参数或参数值错误,详见文本 */
    CNC_RC_ERR_STATE = -3,       /* 状态错误,操作不允许,详见文本 */
    CNC_RC_ERR_CONFIG = -4,       /* 配置错误,例如轴不存在 */
    CNC_RC_ERR_INT = -5,       /* 解释器错误,详见解释器错误状态 */
    CNC_RC_ERR_CE = -6,       /* 命令包错误 */
    CNC_RC_ERR_EXE = -7,       /* 执行错误 */
    CNC_RC_ERR_CPU = -8,       /* CPU错误,详见子代码、文本,需重启 */
    CNC_RC_ERR_MOT = -9,       /* 轨迹生成器错误,详见子代码、文本 */
    CNC_RC_ERR_SYS = -10,      /* 服务端系统错误,详见文本 */
    CNC_RC_ERR_TIMEOUT = -11,      /* 通用超时错误 */
    CNC_RC_EXE_CE = -12,      /* 执行命令包错误 */
    CNC_RC_ERR_FILEOPEN = -13,      /* 文件打开错误 */
    CNC_RC_ERR_COLLISION = -14,      /* 碰撞 */
    CNC_RC_ERR_SERVER_NOT_RUNNING = -15,/* 尝试以监控模式连接,但服务端未运行 */
    CNC_RC_ERR_VERSION_MISMATCH = -16,  /* 服务端与CNCAPI版本不匹配 */
    CNC_RC_ERR_NOT_CONNECTED = -17      /* CNCAPI未调用CncConnectServer */
} CNC_RC;


#define C_DLL_EXPORT __declspec(dllexport)  // 或自定义宏

typedef CNC_RC(__stdcall* pfCncRunSingleLine)(char* text);  // 正确的函数指针类型

extern "C" {  // 确保C风格链接(无名称修饰)
    // 导出函数,返回类型正确(CNC_RC)
    C_DLL_EXPORT CNC_RC CncRunSingleLine(char* text)
    {
        if (text == nullptr)
        {
            ::MessageBoxW(NULL, L"无效输入参数:text为NULL", L"错误", MB_ICONERROR);
            return CNC_RC_ERR;  // 参数无效时返回错误
        }

        // 1) 获取原DLL句柄(根据需要调整DLL名称)
        HMODULE hModule = ::GetModuleHandle(TEXT("_cncapi.dll"));  // 必要时调整DLL名称
        if (!hModule)
        {
            // 未找到原CNC API DLL时显示错误并返回失败码
            ::MessageBoxW(NULL, L"加载原CNC API DLL失败", L"错误", MB_ICONERROR);
            return CNC_RC_ERR;  // 返回错误码
        }

        // 2) 获取原DLL中的函数地址
        pfCncRunSingleLine pOriginalCncRunSingleLine = (pfCncRunSingleLine)::GetProcAddress(hModule, "CncRunSingleLine");
        if (!pOriginalCncRunSingleLine)
        {
            // 未找到CncRunSingleLine函数时显示错误并返回失败码
            ::MessageBoxW(NULL, L"未找到CncRunSingleLine函数", L"错误", MB_ICONERROR);
            return CNC_RC_ERR;  // 返回错误码
        }

        // 3) 调用原函数并返回结果
        CNC_RC result = pOriginalCncRunSingleLine(text);  // 调用函数

        // 检查结果是否有效
        if (result != CNC_RC_OK)  // 必要时替换为正确的成功返回码
        {
            ::MessageBoxW(NULL, L"CncRunSingleLine函数调用失败", L"错误", MB_ICONERROR);
        }

        return result;  // 返回原函数的结果
    }
}

问题详情

  • 拦截函数已被成功调用,执行结果符合预期
  • 函数执行完成后程序立即崩溃
  • 崩溃发生在CncRunSingleLine返回之后,尽管功能已正常实现

已尝试的排查步骤

  • 确认拦截函数被调用且结果符合预期
  • 检查返回值,确认CncRunSingleLine在崩溃前已执行完成
  • 验证hModule正确获取到_cncapi.dll,函数指针有效
  • 通过MessageBoxW确认崩溃发生在CncRunSingleLine返回之后

内容的提问来源于stack exchange,提问作者Felix Prackwieser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:04:57