I am trying to call C# code from C++. So I chose the COM Interop way. Now I have C# code:
namespace ToBeCalled
{
[Guid("9329feaf-b293-4093-a7d8-6128f52b30a6")]
[ComVisible(true)]
public interface IInterface
{
int Write(string toWrite);
}
}
namespace ToBeCalled
{
[Guid("e4105e40-2d6b-4b7c-ae42-d2f9c405a2a0")]
[ComVisible(true)]
public class ClassYouWantToUse : IInterface
{
public int Write(string toWrite)
{
System.Console.WriteLine(toWrite);
return 1;
}
}
}
And c++ code
#import "...\\ToBeCalled.tlb"
int _tmain(int argc, _TCHAR* argv[])
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
// Create the interface pointer.
ToBeCalled::IInterfacePtr piTest(__uuidof(ToBeCalled::ClassYouWantToUse));
long lResult = 0;
// Call the Add method.
piTest->Write("hi", &lResult);
wprintf(L"The result is %d\n", lResult);
// Uninitialize COM.
CoUninitialize();
return 0;
}
When I try this compile, of course it says that Write doesn't take 2 arguments. I saw the MSDN, where they have example like this and they take the return value this way. So my question is, how can I obtain the return value of the function? When I update the call to
piTest->Write("hi");
than execution fails on Unhandled Exception. When I tried this example without returning value, so declaration of the return value for method is void, than everything works ok.
Your server code is OK and you don't need to use an out
parameter.
The client code should look simply like this:
long result = piTest->Write("hi");
If you look inside generated .tlh
file, you will see that signature is something like:
long Write(_bstr_t toWrite);
This is a generated wrapper code, and you are probably confusing it with raw COM call which is also a part of the tlh
file and looks like this:
virtual HRESULT __stdcall raw_Write(BSTR toWrite, long* pRetVal) = 0;
The wrapper is more convenient: it calls the raw COM call internally and handles the return value - thus, the return value is normally returned from the function (instead of as an [out, retval]
argument), and if the result of raw call denotes an error (a failed HRESULT
) a _com_error
exception is thrown.
For details, you can take a look at another generated file, with tli
extension, which contains the implementation of wrapper method.