【发布时间】:2021-08-31 05:47:09
【问题描述】:
我找到了答案,但对我正在尝试做的事情是否定的:
Passing method pointer from C# to Delphi DLL
是否有可能在 C# 中从 Delphi 调用对象委托?因为上面示例中的所有 Delphi 调用者都是静态的并且是导出的。我正在使用 OleVariant,并希望使用 GetDelegateForFunctionPointer 从 C# 中的 Delphi 对象调用调用者。但是当我尝试时,Delphi 事件中的调试器在该方法中中断,然后我得到“尝试读取或写入受保护的内存”。
德尔福代码:
TOnEvent = procedure() of object;
TOnEventStdCall = procedure() of object; stdcall;
TSimpleClass = class
FUserControl: OleVariant;
FOnEventHandler : TOnEvent;
FOnEventStdCallHandler : TOnEventStdCall;
constructor Create();
procedure ProcOnEventStdCall(); stdcall;
end;
...
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(LongInt(@FOnEventStdCallHandler), LongInt(self));
end;
procedure TSimpleClass.ProcOnEventStdCall; stdcall;
begin
ShowMessage('Invoked');
if Assigned(FOnEventHandler) then
FOnEventHandler(); // !!! exception here
end;
和 C# 代码:
struct TMethod
{
IntPtr pMethod;
IntPtr pInstance;
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void TEvent(IntPtr instance);
private TOnEventStdCall _delphiHandler;
public void SetEvent(Int32 method, Int32 instance)
{
m.pMethod = new IntPtr(method);
m.pInstance = new IntPtr(instance);
_delphiHandler += (TEvent)Marshal.GetDelegateForFunctionPointer(m.pMethod, typeof(TEvent));
}
...
_delphiHandler.Invoke(m.pInstance);
我相信有类似的问题,但没有得到答案:
【问题讨论】:
-
这里不够详细,我们需要minimal reproducible example。但是,对 SetDocumentCompleatedEvent 的调用不能做任何有用的事情,因为它只传递了一半的方法,即代码而不是数据。
-
我已经纠正了这个问题,并将尝试准备适当的可执行代码。我正在使用 JCL 在 Delphi 中执行 C# 代码,并尝试削减所有不必要的代码行。
-
仍然遇到同样的问题。你只通过了一半的方法。一个方法是两个指针。你只通过一个。
-
我不明白你写了什么。哪个方法有两个指针?有两种方法。一个“SetEvent”将指针传递给我想在 C# 中调用的 Delphi 中的过程。第二个是不带参数的调用过程。
-
@PawełKępiński
FUserControl.SetEvent是什么意思 - 还有什么?根据第一条评论,您无处传递方法的数据,只传递其代码。
标签: c# delphi marshalling