[Mono-dev] Mono runtime error "Pointers can not reference marshaled structures"

Steve Leibman sleibman at alum.mit.edu
Fri Apr 4 14:23:11 EDT 2008

Hi all,

Possible mono bug -- soliciting feedback before I actually file a bug

I'm having difficulty making calls from C# to functions in native libraries
that take pointers to structs as arguments. I've been able to work around
the issue by using void* pointers in C# instead of pointers to a structure I
define in C#. Nevertheless, based on my (limited) understanding of the way
marshaling is supposed to work, this looks like it may be a mono bug.

Here's the error I see at runtime:

Unhandled Exception:
System.Runtime.InteropServices.MarshalDirectiveException: Can not marshal
'parameter #1': Pointers can not reference marshaled structures. Use byref
  at (wrapper managed-to-native)
  at Isc.StarP.UnmanagedCode.testlibrary.functionThatTakesPtr_W (.structy*
mystruct) [0x00000]
  at libwrapper_test.Main () [0x00000]

Below is an isolated example of code that demonstrates the problem.
To reproduce it, run the following 4 commands (assuming linux + gcc):
gcc -o testlibrary.o -fPIC -c library.c -I.
gcc -shared -Wl,-soname,libtestlibrary.so -o libtestlibrary.so testlibrary.o
gmcs -unsafe -out:libwrapper_test.exe  testlibrary_W.cs libwrapper_test.cs
mono libwrapper_test.exe

The 4 relevant source files are as follows:

 * library.h

#include <stdlib.h>
#include <stdio.h>
typedef struct structy {
  int   blah;
} structy;
void functionThatTakesPtr(structy* mystruct);

 * library.c

#include "library.h"
void functionThatTakesPtr(structy* mystruct) {
  printf ("I found an entry in the structy-struct with value %d\n",
structy* functionThatCreatesStruct() {
  structy* mystruct = (structy*)malloc(sizeof(structy));
  mystruct->blah = 42;
  return mystruct;
int main() {
  structy* mystruct = functionThatCreatesStruct();

 * testlibrary_W.cs

using System;
using System.Runtime.InteropServices;
using System.Security;
using MyChar = System.Void;

namespace Isc.StarP.UnmanagedCode {

  public class testlibrary {
    private const string dllName = "libtestlibrary";

    unsafe public struct structy {int blah;}

    [DllImport(dllName, ExactSpelling=true, SetLastError=false,

    // WORK AROUND (part 1 of 2):
    // Change the following to take a void* instead of structy*
    unsafe static extern void functionThatTakesPtr([In,Out] structy*

    [DllImport(dllName, ExactSpelling=true, SetLastError=false,
    unsafe static extern structy* functionThatCreatesStruct();

    // WORK AROUND (part 2 of 2):
    // Change the following to take a void* instead of structy*
    unsafe public static void functionThatTakesPtr_W(structy* mystruct) {

    unsafe public static structy * functionThatCreatesStruct_W() {
      return (structy*)functionThatCreatesStruct();

 * libwrapper_test.cs

using System;
using SizeType = System.UInt64;
using SignedSizeType=System.Int64;

using Isc.StarP.UnmanagedCode;

public class libwrapper_test
  public static void Main()
    unsafe {
      testlibrary.structy* mystruct =

Steve Leibman
sleibman at interactivesupercomputing.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080404/97d177d0/attachment.html 

More information about the Mono-devel-list mailing list