Question

I need to send a struct from C# managed code to a C library. The C library will populate the values in the struct. I have been trying to pass the struct as a reference so that the C# code will get the updated data values.

This is an example C function in libshlib.so:

void sharedStruct(struct data* d)
{
   d->number = calcSomething();
   d->message = doSomething();
}

I can send individual parameters (int and StringBuilder) and the library code runs and returns new values to the C# code that called it.

But how can I create a struct in C# that contains both int and string and send it to the unmanaged code (C library) which will populate the values to be used back in the C# code?

The C struct might be like this:

struct data
{
  int number;
  char* message;
};

Right now I'm trying to establish the best way to manipulate data in the C library for use in C#. I am writing both pieces of code so I am flexible but right now I haven't been able to get it working.

Was it helpful?

Solution

If you want the struct to be populated by the C code, then you are probably looking for an out variable. Note that the mono runtime by default will use free() to deallocate any strings you pass in and you might have to take extra care with padding in structures (see the StructLayout stuff in msdn). For strings, further problems can be had with character sets.

Sample code:

Managed.cs:

using System;
using System.Runtime.InteropServices;

struct Data
{
    public int number;
    public string message;
}

class Managed
{
    [DllImport("unmanaged")]
    extern static void Foo(out Data data);
    static void Main()
    {
        Data data;
        Foo(out data);
        Console.WriteLine("number = {0}, message = {1}", data.number, data.message);
    }
}

unmanaged.c:

#include <string.h>

struct data
{
    int number;
    char* message;
};

void Foo(struct data* data)
{
    data->number = 42;
    data->message = strdup("Hello from unmanaged code!");
}

Test run:

$ mcs Managed.cs
$ gcc -shared -fPIC -o libunmanaged.so unmanaged.c
$ LD_LIBRARY_PATH=$PWD mono Managed.exe
number = 42, message = Hello from unmanaged code!
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top