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内部持有该指针或做了越界操作,也会出现解析异常。
修复方案
按以下方式修改代码即可:
- 显式声明DLL导入函数,匹配正确的调用约定
- 分配独立的可写char缓冲区存储日期字符串,不要直接传入
c_str()返回的const指针 - 调用完成后释放缓冲区避免内存泄漏
修正后的代码参考:
// 注意根据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
相关产品推荐
相关产品推荐

