从 COM 指针到记录/如何实现(dotNet 的)Marshal.PtrToStructure 的 Delphi 版本
From COM Pointer to Record / How to do a Delphi version of (dotNet's) Marshal.PtrToStructure
寻求有关如何将指针转换/转换为记录的帮助 - 类似于 dotNet 的 Marshal.PtrToStructure 所做的 - 但使用 Delphi.
详细信息:使用 ActiveX / COM(C++ 中的原始代码)。实现允许捕获 ActveX 控件引发的事件的接口。
其中一个已实现接口的方法签名如下所示:
procedure TIUIX_ObjImplEvent.OnEvent(const pSender: IUIX_Obj; const pEvent: IUIX_Event);
IUIX_Event 是一个接口(派生自 IDispatch)。有一个 属性 类型为 Param_T 的 Param1。
Param1 包含指向记录类型的指针。
现在,我有 C# 代码,我想将其转换为 Delphi:
public void OnEvent(IUIX_Obj pSender, IUIX_Event pEvent)
{
//some more code before, and then this part:
IntPtr outPtr = new IntPtr(pEvent.Param1);
UIX_NotifyInfo ni = (UIX_NotifyInfo)System.Runtime.InteropServices.Marshal.PtrToStructure(outPtr, typeof(UIX_NotifyInfo));
}
UIX_NotifyInfo 是一条记录 (/struct)。
问题:如何从pEvent.Param1到ni?使用 Delphi:
procedure TIUIX_ObjImplEvent.OnEvent(const pSender: IUIX_Obj; const pEvent: IUIX_Event);
var
ni : UIX_NotifyInfo;
begin
pEvent.Handled := false;
if (pEvent.Code = e_Notify) then
begin
//how to go from pEvent.Param1 to ni like in C#'s PtrToStructure?
if (ni.nCode = UIX_Notify_BeforeShowPopup) then
begin
pEvent.Handled := true;
end;
end;
end;
我的猜测是使用 Move 过程,但无论我尝试什么,它都无法编译或崩溃:)
Move(??, ni, SizeOf(UIX_NotifyInfo));
我在大卫回答后添加这个...
这是对上述问题的扩展(寻找如何解决 Marshal.GetObjectForIUnknown)。
我有这个 C# 代码:
public void OnEventMonitor(IUIX_Obj pTarget, IUIX_Event pEvent)
{
IntPtr outPtr;
pTarget.QueryImpl(typeof(IUIX_Dialog).GUID, null, out outPtr);
IUIX_Dialog dlg = (IUIX_Dialog)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(outPtr);
}
拥有:
IUIX_Event = interface(IDispatch)
IUIX_Obj = interface(IDispatch)
IUIX_Dialog = interface(IUIX_ObjImpl) (IDispatch)
我的 Delphi 代码(dlg:IUIX_Dialog,pImpl:指针):
pTarget.QueryImpl(GetTypeData(TypeInfo(IUIX_Dialog)).Guid, nil, @pImpl);
Move(pImpl, dlg, SizeOf(IUIX_Dialog));
以上确实有效。
有更好的方法还是正确的方法?
在非托管代码中很简单,只是一个赋值。
var
Rec: TMyRec;
Ptr: Pointer;
....
Rec := TMyRec(Ptr^);
寻求有关如何将指针转换/转换为记录的帮助 - 类似于 dotNet 的 Marshal.PtrToStructure 所做的 - 但使用 Delphi.
详细信息:使用 ActiveX / COM(C++ 中的原始代码)。实现允许捕获 ActveX 控件引发的事件的接口。
其中一个已实现接口的方法签名如下所示:
procedure TIUIX_ObjImplEvent.OnEvent(const pSender: IUIX_Obj; const pEvent: IUIX_Event);
IUIX_Event 是一个接口(派生自 IDispatch)。有一个 属性 类型为 Param_T 的 Param1。
Param1 包含指向记录类型的指针。
现在,我有 C# 代码,我想将其转换为 Delphi:
public void OnEvent(IUIX_Obj pSender, IUIX_Event pEvent)
{
//some more code before, and then this part:
IntPtr outPtr = new IntPtr(pEvent.Param1);
UIX_NotifyInfo ni = (UIX_NotifyInfo)System.Runtime.InteropServices.Marshal.PtrToStructure(outPtr, typeof(UIX_NotifyInfo));
}
UIX_NotifyInfo 是一条记录 (/struct)。
问题:如何从pEvent.Param1到ni?使用 Delphi:
procedure TIUIX_ObjImplEvent.OnEvent(const pSender: IUIX_Obj; const pEvent: IUIX_Event);
var
ni : UIX_NotifyInfo;
begin
pEvent.Handled := false;
if (pEvent.Code = e_Notify) then
begin
//how to go from pEvent.Param1 to ni like in C#'s PtrToStructure?
if (ni.nCode = UIX_Notify_BeforeShowPopup) then
begin
pEvent.Handled := true;
end;
end;
end;
我的猜测是使用 Move 过程,但无论我尝试什么,它都无法编译或崩溃:)
Move(??, ni, SizeOf(UIX_NotifyInfo));
我在大卫回答后添加这个...
这是对上述问题的扩展(寻找如何解决 Marshal.GetObjectForIUnknown)。
我有这个 C# 代码:
public void OnEventMonitor(IUIX_Obj pTarget, IUIX_Event pEvent)
{
IntPtr outPtr;
pTarget.QueryImpl(typeof(IUIX_Dialog).GUID, null, out outPtr);
IUIX_Dialog dlg = (IUIX_Dialog)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(outPtr);
}
拥有:
IUIX_Event = interface(IDispatch)
IUIX_Obj = interface(IDispatch)
IUIX_Dialog = interface(IUIX_ObjImpl) (IDispatch)
我的 Delphi 代码(dlg:IUIX_Dialog,pImpl:指针):
pTarget.QueryImpl(GetTypeData(TypeInfo(IUIX_Dialog)).Guid, nil, @pImpl);
Move(pImpl, dlg, SizeOf(IUIX_Dialog));
以上确实有效。
有更好的方法还是正确的方法?
在非托管代码中很简单,只是一个赋值。
var
Rec: TMyRec;
Ptr: Pointer;
....
Rec := TMyRec(Ptr^);