I have written a COM component in C++ (6.0 - I know its old but I'm learning using it) using the IDispatch interface and am trying to consume it in C#.
My C# code is as follows:
static void Main(string[] args)
{
Type type = Type.GetTypeFromProgID("Bens.General.1");
Object obj = Activator.CreateInstance(type);
ITest tObj = (ITest)obj;
Console.WriteLine("Value1: " + tObj.MyValue());
Console.ReadLine();
}
(I have also tried this using dynamic but no luck there either).
with the following ITest interface:
[Guid("4B8C6960-EB25-11e7-A3BD-001CF0FAD303")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ITest
{
[DispId(1)]
string MyValue();
[DispId(2)]
string Value2();
}
The C++ QueryInterface is:
HRESULT __stdcall Cmpnt::QueryInterface(const IID& iid, void** ppv)
{
char buffer[37];
char* guid = guid_to_str(&iid, buffer);
MessageBox(NULL, guid, guid, 0);
if(iid == IID_IUnknown)
{
*ppv = static_cast<general*>(this);
}
else if(iid == IID_IDispatch)
{
*ppv = static_cast<general*>(this);
}
else if(iid == IID_general)
{
*ppv = static_cast<general*>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
IID_general definitely matches the GUID in the ITest attribute.
What I have tried:
It works fine in VB6 and VBA (Office 2016) but in C# says that the Interface
{
4B8C6960-EB25-11e7-A3BD-001CF0FAD303
}
Isn't implemented but I know for a fact that in the C++ QueryInterface method it is (it works in VB/VBA so why not C#?)
The MessageBox in the C++ code shows the C# is trying at least 10 IID's including the IID_general which seems strange to me with no luck. VBA, Excel shows that it tries 6 IID's and succeeds after that.
UPDATE: I have updates my COM component to support early binding with type library, MIDL generated interfaces, etc... - again this works for VBA (Excel) but not in C#.