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

Delphi调用DLL遇阻:C函数与结构体转换后调用返回0求助

问题分析与修正方案

你的核心问题在于结构体内存布局不匹配、类型定义错误以及参数传递方式不正确,导致DLL无法正确解析传入的数据,最终返回无效句柄。以下是具体修正步骤:

一、错误点总结

  1. 结构体使用了Delphi动态数组(array of Byte),但C语言中是固定大小的静态数组,两者内存布局完全不同,DLL无法识别。
  2. C的ULONG是无符号32位整数,你误用了有符号的Longint,可能导致数据解析异常。
  3. 函数参数语法错误,且未正确传递结构体的指针地址。
  4. 字符串赋值未考虑C端的ANSI编码要求,且未初始化结构体,残留垃圾数据干扰解析。

二、修正后的类型与函数声明

严格匹配C语言的内存布局与类型定义:

// 对应C的ULONG(无符号32位整数)
type
  ULONG = Cardinal;

// 严格对齐C的结构体,packed保证内存布局完全一致
  DAPI_OPENMODULEEX_STRUCT = packed record
    address: array[0..255] of Byte;       // 固定256字节数组,对应C的unsigned char address[256]
    timeout: ULONG;                        // 对应C的ULONG timeout
    portno: ULONG;                         // 对应C的ULONG portno
    encryption_type: ULONG;                // 对应C的ULONG encryption_type
    encryption_password: array[0..31] of Byte; // 固定32字节数组,对应C的unsigned char encryption_password[32]
  end;
  PDAPI_OPENMODULEEX_STRUCT = ^DAPI_OPENMODULEEX_STRUCT; // 结构体指针类型

// 函数声明(调用约定假设为stdcall,多数Windows DLL使用该约定;若DLL实际为cdecl,需替换)
function OpenModuleEx(
  moduleID: ULONG;
  nr: ULONG;
  exbuffer: PDAPI_OPENMODULEEX_STRUCT;
  open_options: ULONG
): ULONG; stdcall; external 'master.dll';

三、正确的调用代码

var
  buffer: DAPI_OPENMODULEEX_STRUCT;
  lhandle: ULONG;
  sAddr: AnsiString;
begin
  // 1. 清零结构体,避免垃圾数据干扰DLL解析
  FillChar(buffer, SizeOf(DAPI_OPENMODULEEX_STRUCT), 0);

  // 2. 设置IP地址:转为ANSI字符串后复制到静态数组
  sAddr := '10.241.0.147';
  if Length(sAddr) > 255 then
    sAddr := Copy(sAddr, 1, 255); // 防止超出数组长度
  Move(sAddr[1], buffer.address[0], Length(sAddr));
  // 数组剩余位置已被清零,自动形成C风格的字符串结尾

  // 3. 设置其他参数
  buffer.portno := 9912;
  buffer.timeout := 5000;
  buffer.encryption_type := 0;
  // 密码为空时无需额外操作,FillChar已将数组清零

  // 4. 调用DLL函数,传递结构体指针
  lhandle := OpenModuleEx(42, 0, @buffer, 0);

  // 检查调用结果
  if lhandle = 0 then
    ShowMessage('OpenModuleEx调用失败,返回句柄为0')
  else
    ShowMessage(Format('OpenModuleEx调用成功,句柄:%u', [lhandle]));
end;

额外说明

  • 调用约定:如果DLL实际使用__cdecl调用约定,需将函数声明中的stdcall改为cdecl,否则会导致栈错误。可通过Dependency Walker工具查看DLL的导出函数调用约定。
  • 64位适配:若使用64位程序,需确认C的ULONG是否为64位(对应Delphi的UInt64),32位程序则保持Cardinal即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:40:32