[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