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

C#调用Delphi的procedure of object对象委托报内存访问错误如何解决

问题根因分析
  • 传参逻辑错误:Delphi侧代码中LongInt(@FOnEventStdCallHandler)传递的是方法指针变量本身的内存地址,而非方法的实际入口地址。Delphi的procedure of object是包含「方法入口地址+对象实例指针」两个字段的结构,你需要拆分结构内的有效字段传递,而非传递结构本身的地址。
  • 调用约定栈失衡:你当前的传参和委托定义会导致执行Delphi方法后栈指针偏移,访问类成员变量(如FOnEventHandler)时读取到错误内存地址,触发保护错误。
  • 若运行在64位环境,用LongInt强制转换指针会发生高位截断,也会导致内存访问错误。
可行解决方案

方案1:直接适配Delphi对象方法指针(修改量小,推荐)

Delphi侧代码修改

拆分of object方法指针的代码段和实例段传递,用NativeInt替代LongInt兼容32/64位环境:

constructor TSimpleClass.Create();
begin
  FHost := TJclClrHost.Create('v4.0.30319');
  FHost.Start;
  FUserControl := FHost.DefaultAppDomain.CreateInstance('CSharpLibrary','CSharpLibrary.Init').Unwrap;
  FOnEventHandler := nil;
  FOnEventStdCallHandler := ProcOnEventStdCall;
  // 核心修改:提取方法指针的代码地址和实例地址传递
  FUserControl.SetEvent(NativeInt(TMethod(FOnEventStdCallHandler).Code), NativeInt(TMethod(FOnEventStdCallHandler).Data));
end;

C#侧代码修改

调整委托存储逻辑,避免多播委托导致的异常,同时将委托声明为全局成员防止被GC回收:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void TEvent(IntPtr instance);
// 全局存储委托和实例指针,避免GC回收导致访问无效内存
private TEvent _delphiHandler;
private IntPtr _delphiInstance;

public void SetEvent(IntPtr methodCode, IntPtr instance)
{
    _delphiHandler = (TEvent)Marshal.GetDelegateForFunctionPointer(methodCode, typeof(TEvent));
    _delphiInstance = instance;
}

// 触发调用的逻辑
public void InvokeDelphiMethod()
{
    _delphiHandler?.Invoke(_delphiInstance);
}

方案2:静态方法中转(兼容性更强)

如果方案1仍存在调用约定适配问题,可以用Delphi静态方法做一层中转,显式传递实例指针,完全规避of object的隐藏参数适配问题:

Delphi侧新增代码

type
  TSimpleClass = class
  // 原有成员保持不变
  public
    class procedure StaticEventProxy(SelfPtr: Pointer); stdcall;
end;

class procedure TSimpleClass.StaticEventProxy(SelfPtr: Pointer); stdcall;
begin
  // 显式转换实例指针后调用目标方法
  TSimpleClass(SelfPtr).ProcOnEventStdCall;
end;

// 构造函数传参修改为静态方法地址
constructor TSimpleClass.Create();
begin
  // 原有逻辑保持不变
  FUserControl.SetEvent(NativeInt(@TSimpleClass.StaticEventProxy), NativeInt(Self));
end;

C#侧代码和方案1完全一致即可正常运行。

内容的提问来源于stack exchange,提问作者Paweł Kępiński

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 19:27:02