2017-10-07 23 views
2

我正在使用COM互操作从C++应用程序调用C#DLL中的方法。创建COM接口指针在开发机器上工作,但导致应用程序崩溃在其他机器上

的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)); 

好像事情是在另一台机器上也许缺少的,但我无法弄清楚什么?

+1

您是否在其他机器上注册了C#COM DLL?你必须使用'regasm.exe'来注册DLL。 – pstrjds

+0

是项目工作目录中的dll,还是放置在您所制作的程序可以访问它的新机器上的某个位置? – holycatcrusher

+0

我不知道我需要注册C#的DLL。每次安装时都需要这样做吗? –

回答

3

当使用暴露COM接口的dll时,该dll需要注册。注册C#COM DLL的工具是regasm.exe。作为安装过程的一部分,您需要在公开COM接口的任何dll上调用regasm。作为调试和帮助自己的一部分,您可以稍微修改代码,以便在尝试创建对象时检查HRESULT,并在需要时进行日志记录。
注意:我没有设置来测试此代码,所以它们可能是一个错字,但它应该指向正确的方向。如果您没有VS创建的“智能指针”,则可以使用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评论编辑 ,以及完成的缘故,有使用COM不registering的dll文件的方式。它涉及创建与应用程序并存的清单文件。

+1

不错。谢谢你的插件:) – MickyD

+1

@MickyD - 信贷到期信贷!你引发了我的记忆。我已经忘记了regfree COM的东西,现在我回想起Don Box的书“Essential COM”花费了数小时的时间......虽然不确定那些是美好的回忆。注意:这并不是对这本书的猛烈抨击,这本书在帮助我理解COM方面非常出色,只是不确定如何使用COM是一段幸福的记忆。 – pstrjds

+0

谢谢你,先生。我从Wrox Press那里得到了大量的COM和DCOM(救救我!)书籍....那些大型的红色封面。是的,现在有更简单的方法来做事情:) – MickyD

相关问题