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

Delphi调用LabVIEW DLL传字符串触发Access Violation问题求助

报错核心原因

触发Access Violation是三个不匹配问题叠加导致的,数学运算类DLL调用正常是因为数值类型参数在stdcall约定下只要宽度匹配很少出现栈错位,字符串传参只要签名、类型、内存任意一环出错就会直接崩溃:

  • 函数签名完全不匹配:DLL导出函数是2个入参、void无返回值,原Delphi端声明的是1个入参、PChar返回值,调用时栈排布完全错误,函数返回时会直接跳转到非法内存地址触发违例。
  • 字符串类型内存布局不兼容:LabVIEW的PStr是Pascal风格短字符串,内存结构为「1字节长度值 + 最多255字节ANSI字符内容,无NULL终止符」;Delphi的PChar是C风格NULL结尾字符串指针,内存布局完全不匹配,传过去后LabVIEW读到的长度值是非法值,会直接越界访问内存。
  • 输出参数内存未提前分配:DLL的第二个参数是输出缓冲区,要求调用方提前申请好足够的内存空间供DLL写入,原代码根本没有给输出参数预留合法内存,还错误把函数按返回指针的形式调用,必然触发内存访问错误。
修复方案

前置类型对齐

LabVIEW的PStr和Delphi原生ShortString内存布局100%匹配,直接用ShortString做参数载体即可,不需要手动构造结构体。

修正函数声明

严格对齐DLL导出的函数签名:两个PLVStr(即^ShortString)入参,无返回值,stdcall调用约定。

正确调用逻辑

提前初始化输入、输出字符串(Delphi会自动为ShortString分配256字节空间,完全满足PStr最大长度要求),传变量地址给DLL,调用完成后直接读取输出字符串即可。

修正后完整代码

type
  PLVStr = ^ShortString;
  TReadStringWriteFunc = procedure(String_input: PLVStr; String_output: PLVStr); stdcall;

var
  hDll: THandle;
  strInput, strOutput: ShortString;
  fReadString: TReadStringWriteFunc;
begin
  hDll := LoadLibrary('C:\Interface.dll');
  if hDll = 0 then Exit; // 原代码hbar>=32的判断是Win16时代遗留写法,32/64位下判断是否为0即可
  try
    fReadString := GetProcAddress(hDll, 'Read_String_In_Write_String_Out');
    if not Assigned(fReadString) then Exit;

    strInput := 'test';
    strOutput := ''; // 初始化输出缓冲区
    fReadString(@strInput, @strOutput);
    
    // 此处strOutput即为DLL返回的原字符串,可直接使用
    ShowMessage(strOutput);
  finally
    FreeLibrary(hDll);
  end;
end;

额外注意事项

  • 平台架构必须匹配:如果LabVIEW生成的是32位DLL,Delphi编译目标必须选32位;如果是64位DLL则必须选64位平台,跨架构加载DLL会直接失败。
  • 不要尝试接收DLL返回的字符串指针:LabVIEW自行管理内部内存堆,跨模块返回的字符串指针随时可能被LabVIEW内存回收,直接访问必然出问题,必须用「调用方分配缓冲区、DLL填充内容」的方式传参。
  • 如果后续需要传递长度超过255的字符串,LabVIEW对应的类型是LStr(长字符串),内存结构是4字节长度+后续字符内容,可自定义数组结构映射,本次可行性测试用的PStr用ShortString即可满足要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:06:09