[Mono-list] Passing structures to pinvoke (or: mono bug)

Pablo Baena pbaena@uol.com.ar
01 Apr 2003 05:24:01 +0000


--=-FYLieRvMdCbjWjopjgsl
Content-Type: multipart/alternative; boundary="=-PvCdiUSTvCR1VWtTQzgy"


--=-PvCdiUSTvCR1VWtTQzgy
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Finally, I can pass a class to pinvoke as an 'out' parameter. Attached
are the samples that runs on .NET, but still won't run on mono.

Cheers!


--=-PvCdiUSTvCR1VWtTQzgy
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/1.1.7">
</HEAD>
<BODY>
Finally, I can pass a class to pinvoke as an 'out' parameter. Attached are the samples that runs on .NET, but still won't run on mono.<BR>
<BR>
Cheers!<BR>
<BR>
</BODY>
</HTML>

--=-PvCdiUSTvCR1VWtTQzgy--

--=-FYLieRvMdCbjWjopjgsl
Content-Disposition: attachment; filename=struct.c
Content-Type: text/x-c; name=struct.c; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit


#include <stdio.h>
typedef struct
{
	char* str;
	int i;
} test_arr_t;
 
typedef struct
{
		test_arr_t* arr;
		int nr_of_arrs;
} test_t;

int modify_it (test_t** testme)
{
	test_t* ptest = (test_t *) malloc (sizeof (test_t));
	if (ptest==NULL) {
		printf ("coņo\n");
		return 0;
	}
	
	ptest->arr = (test_arr_t *) malloc (2 * sizeof (test_arr_t));
	ptest->arr[0].i = 1;
	ptest->arr[0].str = (char *) malloc (sizeof(char)*24);
	strcpy (ptest->arr[0].str, "Hello");
	ptest->arr[1].i = 2;
	ptest->arr[1].str = (char *) malloc (sizeof(char)*24);
	strcpy (ptest->arr[1].str, "baby");
	ptest->nr_of_arrs = 2;

	*testme = ptest;
	return 0;
}

--=-FYLieRvMdCbjWjopjgsl
Content-Disposition: attachment; filename=test2.cs
Content-Type: text/plain; name=test2.cs; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

using System;
using System.Runtime.InteropServices;

namespace teststruct
{
	[ StructLayout( LayoutKind.Sequential )]
	class test_struct_arr
	{
		public string str;
		public int i;
	}
	
	[ StructLayout( LayoutKind.Sequential )]
	class test_struct
	{
		public IntPtr arr;
		public int nr_of_arrs;
	}

	class Class1
	{
		[DllImport ("library")]
		static extern int modify_it (out test_struct p);
				
		[STAThread]
		static void Main(string[] args)
		{
			test_struct testme;
			modify_it (out testme);

			if (testme != null)
			{				
				if (testme.nr_of_arrs != 2)
				{
					Console.WriteLine ("{0} elements? Yeah, right...", testme.nr_of_arrs);
					return;
				}

				test_struct_arr[] tarr = new test_struct_arr[testme.nr_of_arrs];
				IntPtr current = testme.arr;
				
				for( int i = 0; i < testme.nr_of_arrs; i++ )
				{
					tarr[ i ] = new test_struct_arr();
					Marshal.PtrToStructure( current, tarr[ i ]);
				
					//Marshal.FreeCoTaskMem( (IntPtr)Marshal.ReadInt32( current ));
					//Marshal.DestroyStructure( current, typeof(test_struct_arr) );

					current = (IntPtr)((int)current + 
						Marshal.SizeOf( tarr[ i ] ));

					Console.WriteLine ("i[{0}] = {1} {2}", i, tarr[i].str, tarr[i].i);         
				}
			}
			else
			{
				Console.WriteLine ("testme wasn't set");
			}
		}
	}
}

--=-FYLieRvMdCbjWjopjgsl--