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

C++ Builder日期字符串转char*传入DLL函数返回-1如何解决

问题根因

首先纠正一个认知偏差:你在调试器中看到的0x0000000003623480 "2022-07-10"是char*类型的正常显示结果——char*本质是内存指针,调试器会先展示指针指向的内存地址,再展示地址上存储的实际字符串内容。这说明你拿到的指针指向的内容本来就是纯字符串"2022-07-10",不存在所谓"带内存地址的错误值",函数返回-1和这个显示无关。

真正导致调用失败的原因通常是以下两点:

  • 类型不匹配:你定义的cdate是const char*类型,但DLL导出函数fnc_ExtractYear要求的入参是可写的char*。如果DLL内部尝试修改传入的字符串内存,或者编译时开启了严格类型校验,传入const指针会触发内存访问错误,导致函数解析失败。
  • 调用约定/内存约定不匹配:如果DLL函数的导入声明没有指定正确的调用约定(比如DLL用__cdecl你却按__stdcall导入),会导致函数读取参数时栈错位,拿到的根本不是你传入的字符串指针;另外AnsiString::c_str()返回的指针归属AnsiString对象管理,如果DLL内部持有该指针或做了越界操作,也会出现解析异常。
修复方案

按以下方式修改代码即可:

  1. 显式声明DLL导入函数,匹配正确的调用约定
  2. 分配独立的可写char缓冲区存储日期字符串,不要直接传入c_str()返回的const指针
  3. 调用完成后释放缓冲区避免内存泄漏

修正后的代码参考:

// 注意根据DLL实际导出约定调整调用约定,常见为__cdecl或__stdcall
extern "C" __declspec(dllimport) int __cdecl fnc_ExtractYear(char* yyyymmdd);

void __fastcall TfrmMain::btnExecuteClick(TObject *Sender)
{
    int year;
    TDate date;
    AnsiString strdate;

    switch(rdgSelect->ItemIndex)
    {
        case 0:
            date = dtpDate->Date;
            strdate = FormatDateTime("yyyy-mm-dd", date);
            
            // 分配独立可写缓冲区,长度为字符串长度+1,预留字符串结束符\0的位置
            char* cdate = new char[strdate.Length() + 1];
            // 把字符串内容拷贝到独立缓冲区
            strcpy(cdate, strdate.c_str());
            
            year = fnc_ExtractYear(cdate);
            
            // 释放缓冲区
            delete[] cdate;
            
            lblResult->Caption = IntToStr(year);
            break;
        // 其余case逻辑保持不变
    }
}

补充排查点:如果修改后函数仍然返回-1,优先确认DLL要求的字符串编码。如果DLL要求UTF-8编码,把AnsiString换成UTF8String做转换即可,其余缓冲区逻辑不变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:54:31