How to push data from unmanaged to managed code? - c++-cli

I am using a C++/CLI Wrapper to access a purely C++ library (-> unmanaged) from a C# framework (-> managed). I want to build in a mechanism which enables the C++ library to push information about its status towards the framework. In my understanding this means that I will have to call at least a managed function from unmanaged code at some point. Is this possible and how can I achieve this?
Many thanks for your help!
Best regards,
Jakob

Use a delegate to let unmanaged code call a managed method. Marshal::GetFunctionPointerForDelegate() creates a stub that takes care of the transition, calling an instance method is supported. You can cast the returned pointer to a function pointer usable by the unmanaged code.
You'll find a full code sample in this answer.

I would recommend using a (managed) event for this. You could have your C++ wrapper call a method on your C++/CLI generated class which raises the event.
The event can easily be subscribed to from the C# side, and used like any other C# based event.

Related

Using managed objects in native C++ class

I want to call members of a C++/CLI class from native C++ code. Compiler is prohibiting me from doing that. I know that we can use native pointers/references in managed code but don't know way of going opposite. Can anyone help me with this by giving a simple example.Thanks in advance.
It can't be done. Memory layout of managed types is determined by the JIT, so unless your native code uses the CLR programming interface, it has no way of discovering and accessing them. Keeping references visible to the garbage collector is another problem, although overcoming that is more straightforward.
However it is possible to create native types with C++/CLI and those will have a memory layout fixed at compile time, so both managed and native code can use them. That is the way to cross the managed-native boundary in reverse. (Function pointers created from delegates are another way to cross in reverse)

C++/CLI: are local managed variables allowed in unmanaged class methods?

I know gcroot is used for holding a refrence to a managed object in a native class, but what about using managed objects as local variables inside an unmanaged class function ?
The compiler does not seem to generate an error on this, but is it "proper" ? Does it hurt performence?
There is no such thing as a local managed object. All managed objects are stored on the heap, required to let the garbage collector do its job. You could only have a reference as a local variable. A pointer at runtime.
Using an managed object reference in an unmanaged function is possible if you compile that code with /clr or #pragma managed in effect. Such code will be translated to IL and gets just-in-time compiled at runtime, just like normal managed code. It won't otherwise have the characteristics of managed code, there is no verification and you'll suffer all the normal pointer bugs. And yes, it can hurt performance because such code doesn't get the normal optimizer love. The optimizer built in the jitter isn't as effective because it works under time constraints.
Compile native code without the /clr option or use #pragma unmanaged inside your code to switch the compiler on-the-fly.
Managed objects, both values of managed value types (value struct, value class, enum class) and handles to managed reference types (ref struct, ref class) can be used inside code which is compiled to MSIL.
And code that is compiled to MSIL can be part of unmanaged objects (for example, a virtual member function of a standard C++ type can be compiled to MSIL, and the Visual C++ compiler "It Just Works" technology will make sure that the v-table is set up correctly). This is extremely useful when forwarding events and callbacks produced by standard C++ code into the managed GUI world. But it is also applicable if you have an algorithm implemented in managed code (perhaps C#) that you want to call from C++.
As Hans mentions, there are performance implications of switching between MSIL and machine code generation for a particular function. But if you are sitting on a native-managed boundary, then compilation to MSIL and use of the "It Just Works" a/k/a "C++ interop" is by far the highest performance alternative.

How to add and implement a new interface to an Inproc COM server

I've implemented a windows deskband (using the windows SDK sample) and need a way to communicate (one call to start IPC with another application, IPC is already working) with it.
My COM experience is very limited but extrapolating from what I've seen, I think it should be possible to create a new COM interface, implement it in the deskband object (which I have access to via IBandSite), call QueryInterface() for my own interface on it and then use it to call directly into the deskband.
I've tried this but ran into problems very quickly (main reason being: I've no idea what I'm actually doing most of the time ...)
So, my questions are: Is this a viable approach and can someone give me an outline on how to proceed if it is (or point to some resource that could be helpful - short of reading a COM book, which would be my last approach). If it is not, do alternatives come to mind ?
Thank you for your time and best wishes,
Rene.
Here's you path: you add a new interface into .idl file and also if you have a co-class in the .idl file that corresponds to you COM object you list that new interface in the co-class definition. Then you compile the .idl and this gets you a .h file and a .c file with identifiers - the C++ IID and C++ interface definition.
Then you inherit your COM object C++ class from the C++ interface and implement all methods of it. If for whatever reason you can't or don't want to implement a method you have to return E_NOTIMPL from that method implementation.
One very important final thing: you have to change QueryInterface() behavior in you COM object class. If you use ATL you have to add an entry into the COM map. If you don't use ATL change you QueryInterface() - see this question for how to implement QueryInterface() in case of implementing several COM interfaces.

Wrapper to unmanaged code

How would you build a wrapper to unmanaged code in order to use it in managed code, and when exactly do you have to do that?
You don't often need a wrapper, many DLLs with straight-forward exported C functions can be pinvoked with the [DllImport] attribute. An exception for C exports would be a poorly designed DLL that requires the client code to release memory, that can't be done by the managed code since it doesn't have access to the allocator.
The case where you have to have a wrapper is a native C++ class. Managed code cannot pinvoke it directly since it doesn't know how to create an instance of the class (which requires knowing the size of the object and calling the constructor) nor how to destroy it (which requires calling the destructor). It is pretty easy to do in C++/CLI. Very mechanical, the SWIG project can do it automatically. Learning that tool is however more of an investment than learning how to write the wrapper.

c++/cli wrapper question

Is there a recommended way to wrap a native c++ library by c++ cli?
Not sure if one size fits all, but yeah, it is largely a mechanical process. Your ref class wrapper should declare a private member that's a pointer to your native C++ class. Create the instance in the constructor. You'll need a destructor and a finalizer to delete that instance again.
Then for each function in the native C++ class you write a managed version of it. That's almost always a one-to-one call, you simply call the corresponding native method and let C++ Interop convert the arguments. Sometimes you have to write a bit of glue code to convert a managed argument to the native version of it, particularly if your native method uses 8-bit char* or structure arguments.
You'll find that standard pattern in code in my answer here. I also should mention SWIG, a tool that can automate it. Not sure how good it is, never used it myself.