创建 COM 接口指针在开发机器上有效,但会导致应用程序在其他机器上崩溃

Creating COM interface pointer works on development machine but causes application crash on other machine

我正在使用 COM 互操作从 C++ 应用程序调用 C# dll 中的方法。

C#代码是:

namespace MyLibrary
{
  [ComVisible(true)]
  [Guid("f08942b1-db20-44aa-9713-7d28fff51e2b")]
  public interface IMyLibraryInterface
  {
    string POSRequest(string request);
  }

  [ComVisible(true)]
  [Guid("4d962dd5-05ed-431b-82e2-378aebe8d0dc")]
  public class MyLibraryInterface : IMyLibraryInterface
  {
    public string myRequest(string request)
    {
      ....
      return response;
    }
  }
}

调用C++代码为:

CoInitialize(NULL);
MyLibrary::IMyLibraryInterfacePtr MyLibraryInterface(__uuidof(MyLibrary::MyLibraryInterface));
myResult = (LPCTSTR) MyLibraryInterface->myRequest(myInput);
CoUninitialize();

导入相关tlb文件的位置:

#import "MyLibrary.tlb"

这在调试和从我的开发机器 运行 发布版本时都有效,但当我从另一台机器 运行 时导致应用程序崩溃。具体来说,创建指针的那一行似乎是问题所在:

MyLibrary::IMyLibraryInterfacePtr MyLibraryInterface(__uuidof(MyLibrary::MyLibraryInterface));

另一台机器上似乎缺少某些东西,但我不知道是什么?

使用公开 COM 接口的 dll 时,需要注册该 dll。注册 C# COM dll 的工具是 regasm.exe。作为安装过程的一部分,您需要在公开 COM 接口的任何 dll 上调用 regasm。作为调试和帮助自己的一部分,您可以稍微修改代码,以便能够在尝试创建对象时检查 HRESULT,并在需要时进行记录。
注意:我没有测试此代码的设置,因此它们可能有错字,但它应该为您指明了正确的方向。如果您没有 VS 创建的 "smart pointers",您可以使用 CoCreateInstance 调用来创建您的对象,然后检查该调用的 HRESULT。

IMyLibraryInterfacePtr myIntPtr = null;
HRESULT hRes = myIntPtr.CreateInstance(__uuidof(MyLibrary::MyLibr‌aryInterface));
if (!(SUCCEEDED(hRes))
{
    // This means an error occurred, you can log it for debugging, etc.
}

编辑 根据 MickyD 的评论,为了完成,有一种方法可以在没有 registering dll 的情况下使用 COM。它涉及创建与应用程序一起存在的清单文件。