创建 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::MyLibraryInterface));
if (!(SUCCEEDED(hRes))
{
// This means an error occurred, you can log it for debugging, etc.
}
编辑
根据 MickyD 的评论,为了完成,有一种方法可以在没有 registering dll 的情况下使用 COM。它涉及创建与应用程序一起存在的清单文件。
我正在使用 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::MyLibraryInterface));
if (!(SUCCEEDED(hRes))
{
// This means an error occurred, you can log it for debugging, etc.
}
编辑 根据 MickyD 的评论,为了完成,有一种方法可以在没有 registering dll 的情况下使用 COM。它涉及创建与应用程序一起存在的清单文件。