我在Delphi Berlin Update 2下有一个32位和64位编译的COM DLL。在32位和64位VBScript(System \ cscript)中调用COM时完全没有问题。用于64位的exe和用于32位see this post的SysWOW64 \ cscript.exe以获取更多详细信息),如下所示:
set rpm = CreateObject("RPMLib.RadioTracer")
set rpu = CreateObject("RPMLib.Utility")
rpm.SomeMethod();
rpu.SomeMethod();
这意味着我已经成功注册了32位和64位:
regsvr32 RPMLib.dll
delphi编译器将相同的源代码编译为两个版本。所以基本上,32位和64位的GUID是相同的。我已经从_TLB.pas文件
中复制了GUIDLIBID_RPMLib: TGUID = '{D6A7108C-E217-4012-9BAA-E82693CE080C}';
IID_IUtility: TGUID = '{F9372AF6-6DAB-4F3F-B017-73FA147CF563}';
CLASS_Utility: TGUID = '{B1694005-EF15-4ED8-9368-6657C6FE3658}';
IID_IRadioTracer: TGUID = '{0DD935C7-ED78-4ACB-94CE-9981359BBE36}';
CLASS_RadioTracer: TGUID = '{175BB24D-598C-4019-AD29-63FC0A47B11F}';
IID_CallBackFuncs: TGUID = '{05E82013-E197-4C0E-B2C4-504226CC1298}';
我创建了一个C#控制台应用程序(Visual Studio 2015),添加了COM参考并放入代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RPMLib;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var rpu = new Utility();
Console.WriteLine(rpu.Author);
var rpm = new RadioTracer();
Console.WriteLine(rpm.Author);
Console.ReadLine();
}
}
}
如果目标平台是x86,它可以工作。但是,当我切换到x64时,它会抛出此错误(非常令人惊讶仅在创建RadioTracer类时抛出错误而不是另一个抛出错误,例如Utility类):
ConsoleApplication2.exe中发生未处理的“System.InvalidCastException”类型异常 附加信息:无法将“System .__ ComObject”类型的COM对象强制转换为接口类型“RPMLib.RadioTracer”。这个 操作失败,因为QueryInterface调用COM组件 对于IID'{0DD935C7-ED78-4ACB-94CE-9981359BBE36}'的接口 由于以下错误而失败:未指定的错误(来自的异常) HRESULT:0x80004005(E_FAIL))。
RPMLib.dll基本上导出了两个对象,因此您可以创建 RadioTracer()和 Utility()
从Delphi源代码我可以看到它们是在进程中创建的:
TAutoObjectFactory.Create(ComServer, TUtility, Class_Utility, ciMultiInstance,
tmApartment);
TAutoObjectFactory.Create(ComServer, TRadioTracer, Class_RadioTracer,
ciMultiInstance, tmApartment);
最后,这里有一些截图,任何提示?
这是RadioTracer.cs
// Decompiled with JetBrains decompiler
// Type: RPMLib.RadioTracer
// Assembly: Interop.RPMLib64, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: FDE1BB7D-808A-44B6-BE39-4DB3EFA8395B
// Assembly location: c:\RPMLib_Integration_Tests\TestData\Interop.RPMLib64.dll
using System.Runtime.InteropServices;
namespace RPMLib
{
[Guid("0DD935C7-ED78-4ACB-94CE-9981359BBE36")]
[CoClass(typeof (RadioTracerClass))]
[ComImport]
public interface RadioTracer : IRadioTracer
{
}
}
和Utility.cs
// Decompiled with JetBrains decompiler
// Type: RPMLib.Utility
// Assembly: Interop.RPMLib64, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: FDE1BB7D-808A-44B6-BE39-4DB3EFA8395B
// Assembly location: c:\RPMLib_Integration_Tests\TestData\Interop.RPMLib64.dll
using System.Runtime.InteropServices;
namespace RPMLib
{
[CoClass(typeof (UtilityClass))]
[Guid("F9372AF6-6DAB-4F3F-B017-73FA147CF563")]
[ComImport]
public interface Utility : IUtility
{
}
}
其他实验: 我已经删除了32位注册 regsvr32 / u RPMLib.dll ,但问题仍然存在 我试图将32位和64位 interop.RPMLib.dll 添加到项目引用中,而不是选择COM dll本身,它没有帮助。