1

我们已经IXMLHttpRequest在 COM 服务器 (.exe) 中创建了自己的实现,如下所示:

interface IMyXMLHttpRequest : IXMLHttpRequest {
    ...
};

coclass MyXMLHttpRequest {
    [default] interface IMyXMLHttpRequest;
};

问题是,当构建尝试注册 COM 服务器时,我们收到错误“访问 OLE 注册表时出错”。我调试了注册码,它在RegisterTypeLib. 看起来它正试图提取一些与该接口相关的类型信息,IXMLHttpRequest并且(在这里猜测)无法更改与该接口相关的一些注册表项。

从中派生出来是完全错误的IXMLHttpRequest吗?我们是否应该派生IDispatch并让我们的类使用双接口?或者是否有可能从中派生IXMLHttpRequest而我们只是做错了?

更新:我上传了一个可重现的测试用例。我只是使用 Visual Studio 向导生成了一个 ATL COM 服务器,然后我创建了一个派生自它的新接口IXMLHttpRequest和一个实现它的 coclass。如我所述,注册失败。如果我将接口更改为从中派生,IDispatch则它可以正常工作。使用 Visual Studio 2010 在 Windows 7 上 100% 可重现,以提升的权限运行。

4

1 回答 1

1

错误 MSB3073: :VCEnd" 退出,代码为 -2147319780。

仅作记录,错误是0x8002801C TYPE_E_REGISTRYACCESS“访问 OLE 注册表时出错”。

IXMLHttpRequest正如您已经确定的那样,问题在于从类型库之外定义的接口继承。首先通过继承扩展接口基本上不是一个好主意。是的,这是可能的,而且是有道理的,但是一旦您将其放入类型库并具有外部引用,您可能会开始遇到奇怪的问题。

一旦您引用了IXMLHttpRequest,MIDL 编译器也会尝试将其放入您的类型库中。您可以通过查看中间构建文件来见证这一点:

IXMLHttpRequest 的意外副本

这不是你想要的,是吗?您只是想引用它,因为它已经由msxml6.dllsystem32 (syswow64) 目录中的文件中的另一个类型库定义和托管。

主要问题是为什么要从IXMLHTTPRequest. 为什么您认为“正常”的独立新 IDispatch 派生接口在这里不够好?您仍然可以IXMLHTTPRequest在这个 COM 类上实现。那时你不会首先陷入这个麻烦。

无论如何,构建问题是在 IDL 上,编译器IXMLHTTPRequest直接看到来自 Windows SDK 文件的定义。

您想按如下方式更改您的 IDL 文件:

import "oaidl.idl";
//import "ocidl.idl"; // <<--- Make direct IXMLHTTPRequest definition invisible

[
    uuid(7397D60F-A428-42C5-B698-9FA850638074),
    version(1.0),
]
library COMServerTestLib
{
    importlib("stdole2.tlb");
    importlib("msxml6.dll"); // <<--- Reference MSXML type library to import the right interface

在您的 C++ 文件中,您希望使界面对 C++ 代码可见:

#include "stdafx.h"
#include "resource.h"
#include <msxml6.h> // <<--- Re-add IXMLHTTPRequest definition for C++ code
#include "COMServerTest_i.h"

您的项目可以从这里再次构建。

于 2012-12-25T19:42:33.233 回答