Invoke .NET method via COM, with a ref array
See the question and my original answer on StackOverflowLet's suppose you have these C# classes:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class TestClass1
{
public void SayHello()
{
Console.WriteLine("Hello 1");
}
public void TestMethod(ref TestClass2[] parameter)
{
parameter[0].SayHello();
}
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class TestClass2
{
public void SayHello()
{
Console.WriteLine("Hello 2");
}
}
You can register it and create the type library with a command line like this:
%windir%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe ClassLibrary1.dll /codebase /tlb
If you look at the typelib created using OleView from Windows SDK, TestMethod
is declared like this:
[id(0x60020005)]
HRESULT TestMethod([in, out] SAFEARRAY(_TestClass2*)* parameter);
So its a SAFEARRAY
of _TestClass2
pointers (IUnknown
-derived), and you can create it and use it like this (assuming Visual Studio support):
...
#import "c:\mypath\ClassLibrary1.tlb" raw_interfaces_only
using namespace ClassLibrary1;
int main()
{
CoInitialize(NULL);
{
// warning: all error checks omitted
CComPtr<_TestClass1> tc1;
tc1.CoCreateInstance(__uuidof(TestClass1));
tc1.SayHello(); // outputs "Hello 1"
CComPtr<_TestClass2> tc2;
tc2.CoCreateInstance(__uuidof(TestClass2));
SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, 1);
LONG index = 0;
// note this will call AddRef on tc2 so it's safe
SafeArrayPutElement(psa, &index, (_TestClass2*)tc2);
tc1->TestMethod(&psa); // Outputs "Hello 2"
SafeArrayDestroy(psa);
}
CoUninitialize();
return 0;
}