由于 0x8007065E "Data of this type not supported",DllSurrogate 未加载

DllSurrogate not loading because of 0x8007065E "Data of this type not supported"

我正在尝试使旧的 Delphi 32 位 DLL 可用于我的 C# 应用程序。使用默认系统 DLL 代理 (dllhost.exe) 似乎是最舒适的解决方案。

为了证明这可行,我创建了一个最小的 32 位测试 DLL Delphi,它只用一种方法实现了一个接口

HRESULT Add(double a, double b, double* c);

在我的 C# 测试程序中,我首先使用了有效的进程内激活。但是因为要突破32/64位的障碍我们不得不使用DLL Surrogate。所以我添加了必要的注册表项(AppID 等)来完成这项工作,但目前仍将两个模块(DLL 和 C# 测试项目)保留为 32 位。

为确保 DLL 未在进程中加载​​,我 'pinvoked' 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 对象作为引用导入,据我所知,它从类型库创建了一个包装器。

更新 3

我刚刚用 C# 实现了相同的 COM 测试对象,并使其在 COM 中可见。我什至没有导入类型库来创建运行时可调用包装器,而只是尝试使用 CoCreateInstance 获取 IUnknown。同样的错误信息! (顺便说一句,我的测试机器运行 Windows 10)

更新 4

我在 Delphi 中重写了客户端并通过 DLL 代理实例化了两个 COM 对象实现(Delphi 和 C#)。来自 CoCreateInstance 的相同错误消息!

事实证明,所有这些巨大的混乱都是由不正确的注册表设置引起的。要添加到我的 COM 对象的 AppID 条目的 DllSurrogate 值必须留空才能使用系统默认值 dllhost.exe。但是它仍然必须是 REG_SZ 类型,而我的类型被意外创建为 REG_BINARY.