[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
report.

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
instead.
  at (wrapper managed-to-native)
Isc.StarP.UnmanagedCode.testlibrary:functionThatTakesPtr
(Isc.StarP.UnmanagedCode.testlibrary/structy*)
  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",
mystruct->blah);
}
structy* functionThatCreatesStruct() {
  structy* mystruct = (structy*)malloc(sizeof(structy));
  mystruct->blah = 42;
  return mystruct;
}
int main() {
  structy* mystruct = functionThatCreatesStruct();
  functionThatTakesPtr(mystruct);
}


/************************************
 * 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,
CallingConvention=CallingConvention.Cdecl,
EntryPoint="functionThatTakesPtr")]

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

    [DllImport(dllName, ExactSpelling=true, SetLastError=false,
CallingConvention=CallingConvention.Cdecl,
EntryPoint="functionThatCreatesStruct")]
    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) {
      functionThatTakesPtr(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 =
testlibrary.functionThatCreatesStruct_W();
      testlibrary.functionThatTakesPtr_W(mystruct);
    }
  }
}




Thanks!
--
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