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

C# DLL外部函数声明转Delphi遇访问冲突,求正确转换方案

C# DLL函数声明转Delphi的访问冲突问题解决

核心问题分析

  • 参数类型不匹配:C#中的byte[]在P/Invoke中传递的是字节数组的首元素指针,而Delphi的TBytes是动态数组,直接传递TBytes实际传递的是包含长度、引用计数的动态数组元数据指针,而非数据指针。DLL函数会错误地将该指针当作字节数组首地址访问,触发内存访问冲突。你使用PTBytes作为RxData参数,同样错误地传递了动态数组的引用指针,不符合DLL对输出缓冲区的要求。
  • 调用约定可能不匹配:C#的DllImport默认调用约定是Winapi(Windows平台对应StdCall),但如果DLL是C/C++编译的,默认调用约定为Cdecl,调用约定不匹配会导致栈损坏,引发访问冲突。

正确的Delphi函数声明

// 优先尝试StdCall(匹配C#默认设置)
function ExecuteCommand(ComHandle: UInt32; TxAddr, TxCmCode, TxPmCode: Byte;
  TxDataLen: UInt16; TxData: PByte; var RxReplyType, RxStCode0, RxStCode1, RxStCode2: Byte;
  var RxDataLen: UInt16; RxData: PByte): Integer; stdcall; external 'CRT_571.dll' name 'ExecuteCommand';

// 如果上述声明仍报错,尝试Cdecl(DLL为C编译时常用)
// function ExecuteCommand(ComHandle: UInt32; TxAddr, TxCmCode, TxPmCode: Byte;
//   TxDataLen: UInt16; TxData: PByte; var RxReplyType, RxStCode0, RxStCode1, RxStCode2: Byte;
//   var RxDataLen: UInt16; RxData: PByte): Integer; cdecl; external 'CRT_571.dll' name 'ExecuteCommand';

调用示例

var
  ComHandle: UInt32;
  TxAddr, TxCmCode, TxPmCode: Byte;
  TxData: TBytes;
  TxDataLen: UInt16;
  RxReplyType, RxStCode0, RxStCode1, RxStCode2: Byte;
  RxData: TBytes;
  RxDataLen: UInt16;
  RetVal: Integer;
begin
  // 初始化输入参数
  ComHandle := ...; // 填充实际句柄
  TxAddr := ...;
  TxCmCode := ...;
  TxPmCode := ...;
  TxData := ...; // 填充待发送数据
  TxDataLen := Length(TxData);

  // 初始化输出缓冲区(需根据DLL要求设置足够大的长度)
  SetLength(RxData, 256); // 假设最大返回256字节,需根据实际调整
  RxDataLen := Length(RxData);

  // 调用函数
  RetVal := ExecuteCommand(ComHandle, TxAddr, TxCmCode, TxPmCode,
    TxDataLen, @TxData[0], RxReplyType, RxStCode0, RxStCode1, RxStCode2,
    RxDataLen, @RxData[0]);

  // 调整输出数组到实际返回长度
  SetLength(RxData, RxDataLen);

  // 处理返回结果
  if RetVal = 0 then
    // 调用成功,处理RxData等参数
  else
    // 调用失败,处理错误
end;

注意事项

  • 确保输入数组TxData的长度不小于TxDataLen,避免越界访问。
  • 输出缓冲区RxData必须预先分配足够空间,空间大小需大于等于DLL可能返回的最大数据长度,否则会导致内存溢出。
  • 检查DLL位数(32位/64位)是否与Delphi编译的程序位数一致,位数不匹配也会引发访问冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:08:22