QueryInterface上的E_NOINTERFACE注册免费COM

时间:2016-11-17 07:23:24

标签: c# c++ visual-c++ com

以下情景:

  • 包含接口定义的.NET Interfaces.dll
  • VC ++ Project中的COM服务器A,实现接口接口.IA(STA)
  • C#.NET3.5项目中的COM客户端B,实现接口接口.IB

所有内容都必须免费注册,因此dll不会注册。从B创建实例A可以完美无缺。

在B中将A转换为IA失败并出现InvalidTypeCastException(Reason E_NoInterface)。

正确实现IA。我通过在QueryInterface上放置一个断点来验证。对于GUID为IA返回S_OK,并且接口指针也有效。

我进一步调试并意识到在查询接口IA时没有采用STA的标准编组器。

手动返回marshaller(我使用自由线程进行测试)是可行的,因此可以对对象进行转换。但由于A必须在STA中使用,以后会有麻烦。

我有三种可能的解决方案:

  1. 我的清单定义有问题。如果这是固定的,则采用标准编组器并且它可以工作。 (最喜欢的选择)
  2. 我需要手动创建标准编组程序,并在A要求编组时将其交给
  3. 我需要实现一个自定义编组程序(最不可取的选项)。
  4. 还有其他可能吗?我的清单可能有什么问题?

    清单:

    Interfaces.dll:
    
    <?xml version="1.0" encoding="utf-8"?>
    <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
      <assemblyIdentity version="1.0.0.0" type="win32" name="Interfaces"/>
      <file name="Interfaces.dll">
        <typelib tlbid="{[The_tlbid]}"
          version="1.0" helpdir=""/>
        <comClass
          progid="DummyClass"
          clsid="{[dummyClass_clsid]}"
          threadingModel="Apartment" />
      </file>
      <comInterfaceExternalProxyStub 
          name="IA" 
          iid="{[IA_IID]}"
          proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
          baseInterface="{00000000-0000-0000-C000-000000000046}"
          tlbid = "{[The_tlbid]}"  />
      <comInterfaceExternalProxyStub 
          name="IB" 
          iid="{[IB_IID]}"
          proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
          baseInterface="{00000000-0000-0000-C000-000000000046}"
          tlbid = "{[The_tlbid]}"  />
    

    A.dll
    
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity name="A" type="win32" version="1.0.0.0"/>
           ... dependencies here ...
        <dependency>
            <dependentAssembly>
                <assemblyIdentity type="win32" name="Interfaces" version="1.0.0.0"/>
            </dependentAssembly>
        </dependency>
        <file name="A.dll" hashalg="SHA1">
            <comClass clsid="{[A_CLSID]}" tlbid="{[ALIB_TLBID]}" description="A Class" threadingModel="Apartment" progid="A.ClassName">
                <progid>A.A.1</progid>
            </comClass>
        </file>
    

    B.dll
    
    <?xml version="1.0" encoding="utf-8"?>
    <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <assemblyIdentity version="1.0.0.0" name="B" language="neutral" processorArchitecture="x86"/>
      <application/>
      ... irrelevant stuff removed ...
      <dependency>
          <dependentAssembly>
              <assemblyIdentity type="win32" name="A" version="1.0.0.0" />
          </dependentAssembly>
      </dependency>
      <dependency>
          <dependentAssembly>
              <assemblyIdentity type="win32" name="Interfaces" version="1.0.0.0" />
          </dependentAssembly>
      </dependency>
    </asmv1:assembly>
    

0 个答案:

没有答案