2

我正在尝试从 C#(作为插件)使用我的 C++ COM API(加载在 C++ 应用程序中)而无需任何注册。 我按照本教程中的步骤进行操作

所以我所做的是:

  1. 在启动时从我的 C++ 应用程序创建激活上下文。我将我的 COM API 清单文件传递给 CreateActCtx 并通过 ActivateActCtx 启用它
  2. 我的 C# 插件由我的 C++ 应用程序加载(在自定义 AppDomain 内)
  3. 在我的 C# 插件中,我正在尝试 3 种不同的场景。
  • 第一个是在应用程序主线程内创建 COM 对象 --> 这是有效的

  • 第二种是在一个单独的 STA 线程中创建 COM 对象并转换 COM 对象 --> 这是有效的

  • 最后一种情况是在一个单独的MTA线程中创建 COM 对象并强制转换 COM 对象。在这里我有一个问题。我能够创建一个对象,但我无法投射它。我收到了异常,例如:

    Unable to cast COM object of type 'System.__ComObject' to interface type 'API.MyComObjectX'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{DE35BA2A-0566-40D3-AF1D-AD79D1133B09}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))
    

所以下面,代码是我用来测试的代码

/*
Manifest file loaded by my C++ application

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

  <assemblyIdentity type="win32" name="ApiX.X" version="1.0.0.0"/>
  
  <file name="ApiX.dll">
    <comClass clsid="{76125B7A-E5FC-4362-93F8-3B912EB85D51}" threadingModel="Apartment"/> <!-- This define the MyComObjectX object -->
    <typelib tlbid="{4714D4C0-5AA9-47F7-82FF-458B341E7052}" version="1.0" helpdir=""/>
  </file>

  <comInterfaceExternalProxyStub name="IMyComObjectX" iid="{DE35BA2A-0566-40D3-AF1D-AD79D1133B09}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" tlbid="{4714D4C0-5AA9-47F7-82FF-458B341E7052}" baseInterface="{00000000-0000-0000-C000-000000000046}" /> <!-- interface which is based on IDispatch -->

</assembly>

*/

public void testComFreeRegistration(object myComObjectX)
{
    try
    {
        MyComObjectX myComObjectX2 = new MyComObjectX();

        MyComObjectX myComObjectX3 = (MyComObjectX)myComObjectX; // Throw the exception

        MessageBox.Show("working");
    }
    catch (Exception e)
    {
        MessageBox.Show("fail");
        e.ToString();
    }
}


public void EntryPoint(object myComObjectX) // <-- Sent from my C++ application
{

    // The STA test which are working
    // var sta = new Thread(() => testComFreeRegistration(myComObjectX));
    // sta.SetApartmentState(ApartmentState.STA);
    // sta.Start();
    // sta.Join();

    var mta = new Thread(() => testComFreeRegistration(myComObjectX));
    mta.SetApartmentState(ApartmentState.MTA);
    mta.Start();
    mta.Join();
}

另一个奇怪的行为是如果我取消注释我的 STA 测试。两个测试都可以!所以我不知道会发生什么。看来我有一些没有正确初始化的东西。

你知道发生了什么或我应该检查什么吗?为什么 STA <--> MTA 机制似乎没有加载comInterfaceExternalProxyStub配置?

在此先感谢您的帮助 ;)

4

0 回答 0