我试图从我的C#应用程序中使用一个旧的Delphi 32位DLL。使用默认系统DLL代理(dllhost.exe)似乎是最舒适的解决方案。
为了证明这是可行的,我用Delphi创建了一个最小的32位测试DLL,该DLL仅用一种方法实现了一个接口
HRESULT Add(double a, double b, double* c);
在我的C#测试程序中,我首先使用了有效的进程内激活。但是因为要突破32/64位障碍,我们必须使用DLL代理。因此,我添加了必要的注册表项(AppID等)以使其正常工作,但目前仍将两个模块(DLL和C#测试项目)保持在32位。
为确保未在进程中加载DLL,我“粉刺”了CoCreateInstance并像这样使用它:
var adapter = CoCreateInstance(
new Guid("96810C5C-BA59-49D4-9732-EF902B8EFA72"),
null,
CLSCTX.CLSCTX_LOCAL_SERVER,
new Guid("00000000-0000-0000-C000-000000000046"));
后一个GUID是IUnknown,所以我什至没有使用自定义界面进行此测试(当然,我是从我的自定义界面开始的。)
问题在于此代码已经失败并显示以下信息:
0x8007065E "Data of this type not supported"
,我不知道它在谈论什么数据。我以为可能只支持VARIANT类型,所以我将签名更改为以下内容,并且为了进行测试,甚至省略了“ out”参数:
HRESULT Add(VARIANT a, VARIANT b);
还是同样的错误!
有什么想法吗?
更新1
CoCreateInstance的声明是这个
[Flags]
enum CLSCTX : uint
{
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_INPROC_SERVER16 = 0x8,
CLSCTX_REMOTE_SERVER = 0x10
}
[DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
static extern object CoCreateInstance(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
CLSCTX dwClsContext,
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
更新2
为了完整性,我应该提到在Delphi中,该接口是通过Delphi类型库编辑器设计的。然后,在C#中,我导入COM对象作为引用,afaik从类型库创建包装。
更新3
我刚刚用C#实现了相同的COM测试对象,并使它成为COM可见的。我什至没有导入类型库来创建运行时可调用包装器,而只是尝试使用CoCreateInstance获取IUnknown。同样的错误信息! (顺便说一下,我的测试机运行Windows 10)
更新4
我在Delphi中重写了客户端,并通过DLL代理实例化了两个COM对象实现(Delphi和C#)。来自CoCreateInstance的相同错误消息!
答案 0 :(得分:0)
事实证明,所有这些巨大的困惑是由错误的注册表设置引起的。必须将要添加到我的COM对象的AppID条目中的DllSurrogate值保留为空,以使用系统默认的dllhost.exe。但是,它仍然必须是REG_SZ类型,并且我的被意外创建为REG_BINARY。