【问题标题】:Access violation in IActiveScript.AddNamedItem Delphi 64 bitIActiveScript.AddNamedItem Delphi 64 位中的访问冲突
【发布时间】:2015-07-15 11:25:58
【问题描述】:

我正在尝试将应用程序迁移到 64 位,但在使用活动脚本时遇到了一些问题。关于这方面的信息并不多,但我设法找到了一个事实,即有一个 64 位版本的 IActiveScriptParse 接口,因此修改了 GUID defs 以反映如下

  SCATID_ActiveScript = '{F0B7A1A1-9847-11cf-8F20-00805F2CD064}';
  SCATID_ActiveScriptParse = '{F0B7A1A2-9847-11cf-8F20-00805F2CD064}';
  SID_IActiveScript =        '{BB1A2AE1-A4F9-11cf-8F20-00805F2CD064}';
  {$IFDEF WIN64}
    SID_IActiveScriptParse =  '{C7EF7658-E1EE-480E-97EA-D52CB4D76D17}';
    SID_IActiveScriptParseProcedureOld ='{21F57128-08C9-4638-BA12-22D15D88DC5C}';
    SID_IActiveScriptParseProcedure = '{C64713B6-E029-4CC5-9200-438B72890B6A}';
    SID_IActiveScriptError =  '{B21FB2A1-5B8F-4963-8C21-21450F84ED7F}';
  {$ELSE}
    SID_IActiveScriptParse =  '{BB1A2AE2-A4F9-11cf-8F20-00805F2CD064}';
    SID_IActiveScriptParseProcedureOld ='{1CFF0050-6FDD-11d0-9328-00A0C90DCAA9}';
    SID_IActiveScriptParseProcedure =   '{AA5B6A80-B834-11d0-932F-00A0C90DCAA9}';
    SID_IActiveScriptError =     '{EAE1BA61-A4ED-11cf-8F20-00805F2CD064}';
  {$ENDIF}
  SID_IActiveScriptSite =        '{DB01A1E3-A42B-11cf-8F20-00805F2CD064}';
  SID_IActiveScriptSiteWindow =  '{D10F6761-83E9-11cf-8F20-00805F2CD064}';
  SID_IActiveScriptSiteInterruptPoll ='{539698A0-CDCA-11CF-A5EB-00AA0047A063}';
  SID_IBindEventHandler =  '{63CDBCB0-C1B1-11d0-9336-00A0C90DCAA9}';
  SID_IActiveScriptStats = '{B8DA6310-E19B-11d0-933C-00A0C90DCAA9}';

这已经解决了大部分问题,但是当我尝试使用 IActiveScript.AddNamedItem 将我的应用程序 COM 对象添加到脚本对象时,我遇到了一个烦人的访问冲突错误,例如

  ScriptEngine.AddNamedItem(PWideChar(Aname), SCRIPTITEM_GLOBALMEMBERS+SCRIPTITEM_NOCODE+SCRIPTITEM_ISVISIBLE);

对 Scriptengine 的其他调用似乎运行正常,只有这个会产生 AV 错误,并且它在 32 位模式下正常运行。

脚本界面更新有什么我遗漏的吗?

更新:-感谢 Reme Lebeau 对此提供了一些见解。

所以问题出现在 IActiveScriptSite.GetItemInfo 中,这似乎是使用 IActiveScript.AddNamedItem 将对象添加到脚本引擎时发生的回调事件。 IActiveScriptSite 由主机实现,由于某种原因,参数定义在 64 位模式下不起作用。

这是原来的定义

function GetItemInfo(
  pstrName: LPCOLESTR;
  dwReturnMask: DWORD;
  out ppiunkItem: IUnknown;
  out ppti: ITypeInfo): HResult; stdcall;

需要改成

function GetItemInfo(
  pstrName: LPCOLESTR;
  dwReturnMask: DWORD;
  out ppiunkItem: Pointer;
  out ppti: Pointer): HResult; stdcall;

因此,通过顶部描述的 GUID 更改以及对上述函数定义的更改,我们可以同时使用 64 位和 32 位。

【问题讨论】:

  • 嗯,32 位和 64 位会有不同的 GUID 似乎很奇怪。这不正常。因此,在我看来,64 位版本的界面可能与 32 位版本不同,因此决定使用新的 GUID。
  • @David - 是的,如果您在 64 位机器上查看注册表,则有两个版本的 IactiveScriptParse 接口,IactiveScriptParse32 和 IactiveScriptParse64。如果您尝试在 64 位应用程序中使用 32 位接口,则会在各种调用中收到“不支持接口”错误。
  • 在我看来这是一个线索。您是否为此查看过 C++ 标头?具有不同 GUID 的接口是否具有不同的签名?您是否尝试过将 64 位类型库传递给 Delphi 类型库导入器并比较输出?
  • 我还没有找到现代头文件。虽然会有一个 Delphi IDE 可以导入的类型库,但那里也没有任何显示。我假设它在为 64 位编译时获取对我的应用程序 COM 接口的引用不兼容。
  • 显然根据这个bobsotherblog.wordpress.com/2013/09/19/…还有其他问题需要考虑,所以Delphi IDE作为32位进程,不能导入64位类型库。

标签: delphi delphi-xe8


【解决方案1】:

还需要修改 System.ObjAuto

function GetVariantType(TypeInfo: PTypeInfo): TVarType;
...
    tkClass:
      {$IFDEF WIN32}
      Result := varInteger;
      {$ELSE}
      Result := varInt64;
      {$ENDIF}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    相关资源
    最近更新 更多