Home > .Net, C#, C++/CLI > How to marshall C++ reference parameter to C#.NET using C++/CLI

How to marshall C++ reference parameter to C#.NET using C++/CLI

Suppose you have some very complicate function written in either C or native C++. And suppose you want to use it in your C#.NET managed code. Obviously, marshalling is required.
There are generally 3 possible options for marshalling:
1) COM
3) C++/CLI
2) Pinvoke (Platform Invokation)

Since making a COM wrapper for native code (ATL e.t.c) is not trivial, and C++/CLI is usually used for more complicated cases, most used way is platform invokation: define the function as “static extern”, add “DllImport” attribute, define some parameters and – eureka! – the required managed function is ready for using…
In case of native C++ class’s method, the process is a bit more complicated, because compiler concatenates a class & method names in some strange form. Still, the new method name could be acheived using known for all “Dependency Walker” application.

Now for the “strange” case. Let’s take a brief look of simple function in native C++:

bool NativeDivide(int number1, int number2, int& result)
        if (number2 == 0)
                return false;

        result = number1 / number2;
        return true;

How can we use Pinvoke in this case? And here is the answer: we can not! There is no way to marshal the 3rd parameter – referense to integer. What we gonna do? Make a COM component – with factory, interfaces, GUID, etc? No, we don’t want to do a lot of work for a little function… So? Right! We will create some “very simple” C++/CLI wrapper! Remember, that C++/CLI code can contain both native and managed code, being a kind of “glue” between two so different worlds.

Look to the next code and see, how simple it is:

        public ref class AlgorithmWrapper
                bool Devide(int number1, int number2, int% result)
                        int tempResult;
                        bool success = NativeDivide(number1, number2, tempResult);

                        if (success)
                                result = tempResult;

                        return success;

“tempResult” variable is required, because “int%” type can not be converted into “int&” directly.
The function has boolean return value, just to prevent a question of type: “why don’t you return the result by return value” 🙂

Now, if we reference the C++/CLI output dll, which is referenced as a usual .NET dll, we can use it in that simple way:

class Program
        static void Main(string[] args)
                int result = 0;
                AlgorithmWrapper algorithmWrapper = new AlgorithmWrapper();
                algorithmWrapper.Devide(10, 5, ref result);
                Console.WriteLine(string.Format("The result is {0}", result));

And this means, that our problem is solved.
Conclusion: if reusing native dll’s, C++/CLI rules! 🙂

Categories: .Net, C#, C++/CLI Tags: ,
  1. No comments yet.
  1. No trackbacks yet.