Project Mono: C++to C# pointer passing in Linux

Hey there,

today’s assignment is to pass C++ object pointers to a C# dll and back, while running in Linux. What? Linux? Yes! You read it right! By using the Mono runtime, you are able to use C# libraries from a C++ program, passing objects & callbacks, setting & retrieving data and so on. The only thing you need is embedding Mono (its logo is shown above and it depicts a gorilla,yeap), C++ and your C# dll, and that is all. Mono will allow you to control the way that your C++ program will interact with the dll, by calling different exposed dll functions from your C++ program.

Why to exchange data between C++ and C#?

Software reusability could be one reason. Imagine that you have a C# application that implements a basic GUI and an engine, which is responsible for all calculations that are performed by the program, based on the user input. At some point, you figure that your application’s performance could be better and that some of your calculations could be optimized. After optimizing your C# code, you decide that your program could be more performant if it is implemented in a more lower level language, such as C and C++. Although, you wouldn’t like to implement both the GUI and the engine subsystems from scratch. Indeed, the GUI could be reused while the engine could be reimplemented in C++. You could wrap all your GUI operations in a DLL, implement the engine in C++, glue Mono between them in order to exchange information and you are ready to go!

The availability of a specific library could be very limited to only some platforms/languages and that platform (C#, Windows) is not your project’s native (C++,Linux). Instead of reinventing the whole functionality in C++ & Linux, why not just fetch the C# dll, wrap it up in another C# dll (that you will write) and then expose all the API/exported functions to your C++ programs/environment? This is a way better solution, allowing you to:

  • reuse code,
  • treat the C# dll functionalities as a black box,
  • limits the amount of new code to just code that sets up Mono & performs calls through Mono.

Assignment Description

Create a C++ program in Linux that passes a C++ object pointer (Container*) to a C# method, which fills up the object with data that were produced in the C# side. So basically, you will need something like this:

Untitled Diagram (1)

One nice question that could come in mind is, why is there a shared library (*.so) and not just one executable that calls Mono-runtime and the DLL, why do we need the shared library in the middle? Because we decided that only the shared library implements the actual store data function, which also is exposed to the DLL. After calculating the data, the DLL calls the shared library’s exported store function, by passing the pointer that was received during the initial Mono call from the shared library to the DLL. The C# side does not know the actual data structure implementation of the container that was passed to it, actually it doesn’t know that an actual object pointer was passed into it at the first place. Why is that? Because we decided to pass the pointer as an unsigned int of 64 bits (uint64_t)! The C# side just needs to call the exposed stored data function, pass the pointer-integer and the data into the C++ function. The exposed C++ static function will convert the integer back to pointer (Container*), add the data in the container and return. After the initial call of the C++ shared library function to the C# dll, the container object in the C++ side is filled up with the data that the C# side just generated. Sounds interesting & challenging enough? Let’s see how it can be done!




  • C++ 11
  • Mono runtime: apt-get install mono-devel
  • Makefile


Demo Time

1. The DLL (C# .Net side)

Our DLL contains one class, the class Program that contains three functions:

  • superCalculation, the actual functionality that we would like to reuse from C++ through Mono to C#
  • storeResults, the function that is exposed through our C++ shared library and knows how to restore the actual C++ object pointer and store the data that we received from a call to the superCalculation method
  • process, the entry point method that is called from the C++ side and triggers the calculation and the data storing scheme
using System;
using System.Collections.Generic;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace TestDLL
    class Program
        public static List<int> superCalculation()
            //Actual name of the function should be: "dateNowToIntegerList"

            List<int> result = new List<int>();
            string dateString = DateTime.Now.ToString();
            for(int i = 0;i<dateString.Length;i++)
                if (Char.IsNumber(dateString[i]) == false) continue;
                result.Add(Int32.Parse( dateString[i].ToString() ));

            return result;

        [DllImport("./", EntryPoint = "storeResults")]
        public extern static void storeResults(System.UInt64 container, int value);
        [DllExport("process", CallingConvention = CallingConvention.Cdecl)]
        public static void process(System.UInt64 container)
            List<int> results = superCalculation();
            for (int i = 0; i < results.Count; i++)
                storeResults(container, results[i]);


By using the attribute DllImport, you allow the C# compiler to know that at some point, a storeResults method implementation will be available to the DLL from somewhere outside the DLL. By setting the name of the shared library and the entrypoint string, you map the method implementation & a method name symbol  with an external library, allowing the compiler to know where exactly to find the implementation of the storeResults method, that is inside the shared library “”, in the entry point method “storeResults” of the shared library.

 On the other hand, by using the attribute DLLExport before the declaration of the method process, you inform the compiler that this method should be publicly exposed to the outside world, allowing other programs that load the TestDLL to call the process method from the outside. The attribute DLLExport is available through the RGiesecke module that we fetched earlier through NuGet.

After creating a new project in Visual Studio that contains the code above, build it. You will get a nicely packed dll. Now copy the dll to your Linux box, in a new directory, where our Mono project will live.

2. The shared library (C++ Linux)

Our shared library consists of one header file (Kazelib.h) and one implementation file (Kazelib.cpp).

2.1 The header (Kazelib.h)

The header contains the implementation of the Container class, which is the object that will store the results that we retrieved by calling Mono and C#.

#include <vector>
#include <cstdint>
#include <iostream>

class Container {
        std::vector<int> m_Values;
        void storeValue(int value)

        void dump()
        	for(auto &i : m_Values)
        		std::cout << i << std::endl;

//Entry point for C++
extern "C" void process(void);

//Used by C# to store the results
extern "C" void storeResults(uint64_t container,int value);

The header exposes two functions, the process and the storeResults public functions. The first will be exposed to our client program to call; the user program after loading, will call the function process in order to trigger the whole function call sequence. The storeResults function is exposed to the C# universe, allowing us to call it from the C# side. As parameters, storeResults will accept the container object pointer-integer and an integer value that will be stored in the instance of the container object.

2.2 The implementation (Kazelib.cpp)

The logic written in the implementation file knows how the Container object looks like (it includes Kazelib.h) and knows how to set up Mono and invoke the exposed C# method in order to fill the Container object. Kazelib’s entry point is the function process, which is publicly exposed for anyone that would like to use A call to the function will call the private function processThroughMono that will perform the following steps:

  • initialize Mono runtime by loading our dll by name
  • load the appropriate assembly from the dll
  • traverse through the symbols of the assembly by scope, in order to find the MonoMethod object process located in namespace <TestDLL>, class <program>, method name <process> ( the “TestDLL.Program:process” string)
  • instantiate a Container object
  • reinterpret cast it to 64-bit unsigned integer
  • fill the container as void* argument that will be passed to the C# side
  • call process through Mono
  • close Mono runtime

Tip: during a lifetime of a program, the function mono_jit_init should be called only once, this means that you cannot turn Mono on and turn off and then turn on etc. It is allowed only once, meaning that a second call in the same process will fail.

#include "Kazelib.h"
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <assert.h>
#include <mono/metadata/debug-helpers.h>

static void processThroughMono(std::string& dll)
    //Initialize mono runtime
    MonoDomain* domain = mono_jit_init (dll.c_str());
    MonoAssembly *assembly;

    assembly = mono_domain_assembly_open (domain, dll.c_str());

    MonoImage *image =  mono_assembly_get_image  (assembly);
    MonoMethodDesc* desc = mono_method_desc_new ("TestDLL.Program:process", true);

    MonoMethod* method = mono_method_desc_search_in_image (desc, image);

    //Create our container
    Container* c = new Container();

    //Cast to uint64
    uint64_t ptr = reinterpret_cast<uint64_t>(c);

    //Fill it as an argument before the mono method invokation
    void* args[1];
    args[0] = &ptr;

    //Invoke C# code
    mono_runtime_invoke (method, nullptr, args, nullptr);

    //Clean mono runtime
    mono_jit_cleanup (domain);

    //We did it!


void process()
    std::cout << "process()!!" << std::endl;
    std::string dll("test.dll");

void storeResults(uint64_t container,int value)
    Container* c = reinterpret_cast<Container*>(container);

The implementation of the exposed function to the C# universe (storeResults) casts the integer back to an object and then stores the integer value that was passed to the object. The DLL will call it as many times it needs to fill all integer results from the superCalculation C# call.

3. C++ Client Code (main.cpp)

The client code loads (dlopen & dlsym) the shared library by name (process) and then triggers the whole function call sequence by calling the shared library’s process function. Then it unloads (dlclose) the shared library and returns.

#include <iostream>
#include <assert.h>
#include <dlfcn.h>

bool process(std::string &lib, std::string &function)
    void *handle;
    void (*process)(void);
    char *error;

    handle = dlopen (lib.c_str(), RTLD_LAZY);

    if (!handle) {
        fputs (dlerror(), stderr);
        return false;

    process = (void (*)(void)) dlsym(handle, function.c_str());
    if ((error = dlerror()) != nullptr)  {
        fputs(error, stderr);
        return false;
    return true;

int main(int argc, char** argv)
    std::string lib("./");
    std::string function("process");
    assert ( process(lib, function) );

4. Compile (Makefile)

The Makefile consists of the following commands:

g++ -std=c++11 -Wall -fPIC -O2 -c Kazelib.cpp Kazelib.h  `pkg-config –cflags –libs mono-2`
g++ -std=c++11 -shared -o Kazelib.o   `pkg-config –cflags –libs mono-2`
g++ -std=c++11 main.cpp -ldl

The “-ldl” switch is used in order to link our executable against the dynamic linking library, allowing the compiler to find the symbols of dlopen, dlsym and dlclose. The `pkg-config –cflags –libs mono-2` part of the command allows us to find & link against lib Mono’s runtime, allowing us to use any Mono symbol.

5. Run

gclkaze@tzertzelos:~/Desktop/Projects/Tzertzelos/Mono$ make all
g++ -std=c++11 -Wall -fPIC -O2 -c Kazelib.cpp Kazelib.h  `pkg-config –cflags –libs mono-2`
g++ -std=c++11 -shared -o Kazelib.o   `pkg-config –cflags –libs mono-2`
g++ -std=c++11 main.cpp -ldl
gclkaze@tzertzelos:~/Desktop/Projects/Tzertzelos/Mono$ ./a.out


Yes, we did it! We were able to pass our new container C++ object through Mono to C#, fill it with data & print its contents in the C++ side by calling the dumps method call. If you may have noticed, the actual “super calculation” performed in the C# side consist of the conversion of the current date time during execution into an integer list, thus, every time you execute the client program, the Container object will be filled with different numbers. It seems that the previous screenshot was taken at exactly 15th of May 2016,11:07:23.

Summary of what we have learned

I hope i gave you an idea about the following:

  • what is Mono & how can we use it in Linux
  • load shared library and call a function from it
  • compile shared library in Linux
  • the DLLImport & DLLExport attributes
  • cool usage of reinterpret cast
  • export functions from C++ to C#
  • export functions from C# to C++
  • how to pass pointers from C++ to C# and back to C++

In the Linx section below, you will find a github link that points to the actual repo that contains all source files that were shown during this demo.

As you read, this post was quite colossal in terms of information and tried to keep it short as much as possible. Based upon all of this information, i could easily think and write about at least 5 articles for different subjects encountered in this post. I tried to focus in the high-level goal and its sequence of high-level steps and not in the lower-level ones, such as detailed information about “MonoImage” and “MonoDesc” objects. I am sure you will find what you need by clicking the attached links.

Now, go & reuse some code by using Mono in Linux!




Send email from gmail with Python


today’s assignment is to send a text email to an arbitrary recipient by using an existing gmail account. We will send the email by using the blog’s favorite scripting language, Python. For you who wonder if we could attach an image or an arbitrary file to an email & send it with the main content, yes, we can, but in this article i would like to focus simply on text emails, without attachments.


  • An existing gmail account
  • Python’s S(imple)M(ail)T(ransfer)P(rotocol)lib module. smtplib is already installed with Python, thus you don’t need to “pip search” & “pip install” it.


With the following script, we can send an email to any number of recipients (“”) through our existing gmail account (“”). We need to build our email by filling the email content string (the variable message), then logon to the gmail server through the server’s smtp daemon, send the message & finally close connection with the smtp daemon of the gmail server. We use the smtp protocol because in the gmail case, gmail’s servers (to which we need to login in order to send the email) have attached & running an smpt daemon-service, allowing them to “listen” to smtp email requests.

def send_email(user, pwd, recipient, subject, body):
   import smtplib
     gmail_user = user
     gmail_pwd = pwd
     FROM = user
     TO = recipient if type(recipient) is list else [recipient]
     SUBJECT = subject
     TEXT = body     # Prepare actual message
     message = “”“\From:%sTo:%s\nContent-type:text/html\n
                 Subject:%s\n\n%s”“” % (FROM, “, “.join(TO), SUBJECT, TEXT)
     #print message
         server = smtplib.SMTP_SSL(“”)
         server.login(gmail_user, gmail_pwd)
         server.sendmail(FROM, TO, message)
         #print ‘successfully sent the mail’
        return True
     except Exception as e:
         print repr(e)
           #print “failed to send mail”
         return Falseif __name__ == ‘__main__’:
    ‘Not a spam!’,
    ‘You listen,i code!’)


Gmail Login Failure

In case the login() call fails with the following error

Please log in via your web browser and then try again


The page says: “Some apps and devices use less secure sign-in technology, which makes your account more vulnerable. You can turn off access for these apps, which we recommend, or turn on access if you want to use them despite the risks”

and click on “Turn On” (if you want Google to allow you to send the email through your app/script).

At the moment, i have no clue how to send an email without turning that account feature to “Off“. Consider this as an assignment for yourself 🙂

Why wanting to send emails?

Because you would like to get notified by one of your programs in case of

  • an abnormal behavior,
  • a task completion,
  • a data change,

in general, in case specific conditions have been met inside your code & something interesting just happened, while you are away from the console that executes your precious script. By using smtplib through the previous function, you could just fill the subject & content depending the occasion inside your code.

Now, go & spam yourselves.