This questions builds upon the code linked in this question
In my research for custom Marshalling i came across this article and it gave me all the insight i needed to create my own Proxy/Stubb without the help of visual studio.
here is the link to the full project, follow the exact same instructions in this question to get the server and client up & running
So Whats the problem?
First let me tell what isn't the problem
Everything gets set up exactly as planned on both ends until errors randomly occur. When i say random i mean it,
I have been debugging this for over a day now and still can't pinpoint why these segments of code keep failing at random which is why I'm asking help here in debugging.
If anyone does manage to get this code working then the Com Client should communicate with COM server and you will see output like this on the client side
Click 1
Scroll 10
Key Pressed 5
Key Released 10
Basically the COM server sends these strings as char arrays from the STUB to the PROXY and the proxy finally prints the received values.
Note that Standard marshaling using the generated RPC proxy/stub is not a Visual Studio feature, it's provided by the Windows SDK. MIDL, the .IDL compiler is a SDK tool that generates the default P/S files (.c, .h, etc.), so it's really a Windows feature.
Visual Studio (general tooling, often used in conjunction with ATL) just simplifies this invoking MIDL for you.
Now, doing standard marshaling without the generated proxy/stub is still possible, but I wouln't recommend it, unless you have good reasons to do so. Reasons would include very specific optimisations in transferring arguments back & forth, that you know you can use, and you know the system can't. For example a specific type of parameter (like a string or a byte array) that the generated RPC code will transfer using big chunks of memory and you can transfer differently (like some shared handle to something internal to your specific context).
It now works in the repo mentioned, so let's go back to some glitches that had to be fixed:
pUnkOuter
argument passed to the IPSFactoryBuffer::CreateProxy method, so AddRef
it at least, Release
when finished.pUnkOuter
must also be delegated all QueryInterface
calls for any other interface that is not IRpcProxyBuffer
and that is not a proxied interface: IMouse
, IKeyboard
, etc.. (these must be implemented by the proxy implementor of course)pUnkOuter
is not used.iMethod
is set after the GetBuffer
call, the stub's IRpcStubBuffer::Invoke will never be reached and the proxy will get an RPC_E_INVALID_HEADER
error (0x80010111) in the pStatus
out argument of the SendReceive method. Note the "Inside COM+" book is wrong here (or maybe things have changed since but I doubt it).Other remarks:
AddRef
and Release
implementations thread-safe, for example using InterlockedIncrement and InterlockedDecrement instead of ++
and --
operators. Good practise, makes everyone's like easier.AddRef
when giving back an interface to the caller (as always with COM).