tj_ush
tj_ush

Reputation: 69

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

I am using COM interop to call a method in a C# dll from a C++ application.

The C# code is:

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;
    }
  }
}

The calling C++ code is:

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

where the relevant tlb file has been imported:

#import "MyLibrary.tlb"

This works both when debugging and running a release version from my development machine, but causes the application to crash when I run this from another machine. Specifically, the line creating the pointer appears to be the issue:

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

It seems like something is perhaps missing on the other machine but I can't figure out what?

Upvotes: 1

Views: 269

Answers (1)

pstrjds
pstrjds

Reputation: 17438

When using a dll that exposes a COM interface, that dll needs to be registered. The tool for registering a C# COM dll is regasm.exe. As part of your install process you need to call regasm on any dll that exposes a COM interface. As part of debugging and helping yourself, you can modify your code slightly to be able to check the HRESULT when you try to create the object, and log if needed.
Note: I don't have the setup to test this code, so their may be a typo, but it should point you in the right direction. If you don't have the "smart pointers" that VS creates, you can use the CoCreateInstance call to create your object and then check the HRESULT from that call.

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.
}

Edit Based on the comment from MickyD, and for sake of completion, there is a way to use COM without registering the dlls. It involves creating manifest files that live alongside the application.

Upvotes: 2

Related Questions