The background is that I have an external C# dll distributed as a private nuget package from colsultants, this library should be consumed by C# .net 4.x projects (and here no problem at all) but also by C++ projects written in Visual Studio.
Having already discarded approaches like interprocess communication with pipes/sockets/mailslots/memory sharing and to include the .net runtime in C++ projects in order to invoke the C# methods I thought that COM Interop would be the simplest solution to implement.
Following the samples on Microsoft Learn portal and other sources I've started declaring a simple interface and explicit class like this:
using System;
using System.Runtime.InteropServices;
namespace OrionLibCOM.Interfaces
{
[ComVisible(true)]
[Guid("E394732D-E4C3-4D82-BC5F-1B41CD897D66")]
public interface IOrionLicensingCOM
{
void Initialize();
void Activate(string ActivationCode);
void Deactivate();
void PullRemoteState();
bool Refresh();
}
}
using OrionLibCOM.Interfaces;
using System.Runtime.InteropServices;
namespace OrionLibCOM
{
[ComVisible(true)]
[Guid("03FC9138-468B-4B4A-A978-FDEC40C833BB")]
[ClassInterface(ClassInterfaceType.None)]
public class OrionLicensingCOM : IOrionLicensingCOM
{
private ExternalLibFromNuget.MainClass _instance;
public OrionLicensingCOM()
{
_instance = new ExternalLibFromNuget.MainClass();
}
public void Initialize()
{
_instance.Initialize();
}
public void Activate(string ActivationCode)
{
_instance.Activate(ActivationCode);
}
public void Deactivate()
{
_instance.Deactivate();
}
public void PullRemoteState()
{
_instance.PullRemoteState();
}
public bool Refresh()
{
return _instance.Refresh();
}
}
}
Then, after succesfully registering the compiled dll with the command "RegAsm.exe mybinpath\OrionLibCOM.dll /codebase /tlb" I've made a small C++ client in order to test the function calls:
#import "<mybinpath>\OrionLibCOM.tlb"
#include <iostream>
#include <atlstr.h>
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
int main()
{
try
{
TESTHR(CoInitialize(0));
OrionLibCOM::IOrionLicensingCOMPtr LicPtr = nullptr;
TESTHR(LicPtr.CreateInstance("OrionLibCOM.OrionLicensingCOM"));
LicPtr->Initialize();
LicPtr->Activate("asadsjfidsjfisd");
bool status = LicPtr->Refresh();
CoUninitialize();// Uninitialize COM
}
catch (const _com_error& e)
{
CStringW out;
out.Format(L"Exception occurred. HR = %lx, error = %s", e.Error(),
e.ErrorMessage());
MessageBoxW(NULL, out, L"Error", MB_OK);
}
return 0;
}
The problem is that I always get an exception when I try to create the instance of "OrionLibCOM.OrionLicensingCOM", the exception says that the class is not registered. About this the class not registered is the one coming from the external lib since, if I remove "new ExternalLibFromNuget.MainClass();" from "OrionLicensingCOM" class the code runs fine.
Now, since for obvious reasons I cannot mark the provided external lib as "ComVisible" is there a way to use this library, another way to call the COM instance or another way to use COM in order to make it work and use it from C++ code or it's simply not possible to achieve that?