[Mono-devel-list] ORBit2 binding

Jonathan Pryor jonpryor at vt.edu
Mon May 10 07:46:53 EDT 2004


On Sun, 2004-05-09 at 19:24, David Voit wrote:
<snip/>
> Some questions:
> - Is it possible to DllImport extern variables

No.  DllImport can only be applied to method declarations.

(Furthermore, Windows PE object format doesn't support exporting
variables.  Anything that looks like an exported variable, such as
``__declspec(dllexport) int my_variable;'' is actually wrapped by a pair
of functions to get and set the variables value.)

> - Howto generate pointer arrays like this in C#:
> gpointer _args[1];
> char *string = "Hello World";
> 
> _args[0] = &string;

>From the looks of things, you shouldn't need to write code like that. 
In the code you provided, the only place that construct is used is in
get_string(), which is only called to provide an argument to
ORBit_c_stub_invoke().

Since all _args *really* is is a ``char**'' variable, you could just let
the runtime handle this with it's built-in marshaller:

        [DllImport("libORBit-2.so.0")]
        public static extern void ORBit_c_stub_invoke (IntPtr obj,
                                                       IMethods[] methods, 
                                                       long method_index,
                                                       IntPtr ret,
                                                       string[] args,
                                                       IntPtr ctx,
                                                       IntPtr ev,
                                                       long class_id,
                                                       long method_offset,
                                                       IntPtr skel_impl);

This could be invoked as:

	ORBit_c_stub_invoke(echo, imethods, 0, IntPtr.Zero,
		new string[]{"Hello, World!"}, 
		IntPtr.Zero, ev, 0, 4, IntPtr.Zero);

This isn't a direct match, as ``new string[]'' is really a ``const
char**'' -- that is, ORBit_c_stub_invoke can't modify the string
referred to.  However, this is also the case with your existing
get_string() function, as "Hello World!" would likely be stored in a
read-only data segment, so if ORBit_c_stub_invoke attempted to change
it, you'd get a bus error/SEGV.

 - Jon

> If i get these solved I could drop libglue.so
> 
> Now to the Code it compiles, but it fails in ORBit_c_stub_invoke on
> execution.
> 
> >> glue.c
> #include <orbit/orbit.h>
> 
> CORBA_ORB orb_init (char *orb_identifier, CORBA_Environment *ev)
> {
> 	int argc = 1;
> 	char *argv[1];
> 	argv[0] = "test";
> 
> 	return CORBA_ORB_init (&argc, argv, orb_identifier, ev);
> }
> 
> CORBA_TypeCode get_typecode (CORBA_TCKind kind)
> {
> 	switch (kind)
> 	{
> 		case CORBA_tk_null: return TC_null;
> 		case CORBA_tk_void: return TC_void;
> 		case CORBA_tk_short: return TC_CORBA_short;
> 		case CORBA_tk_long: return TC_CORBA_long;
> 		case CORBA_tk_longlong: return TC_CORBA_long_long;
> 		case CORBA_tk_ushort: return TC_CORBA_unsigned_short;
> 		case CORBA_tk_ulong: return TC_CORBA_unsigned_long;
> 		case CORBA_tk_ulonglong: return TC_CORBA_unsigned_long_long;
> 		case CORBA_tk_float: return TC_CORBA_float;
> 		case CORBA_tk_double: return TC_CORBA_double;
> 		case CORBA_tk_longdouble: return TC_CORBA_long_double;
> 		case CORBA_tk_boolean: return TC_CORBA_boolean;
> 		case CORBA_tk_char: return TC_CORBA_char;
> 		case CORBA_tk_wchar: return TC_CORBA_wchar;
> 		case CORBA_tk_octet: return TC_CORBA_octet;
> 		case CORBA_tk_any: return TC_CORBA_any;
> 		case CORBA_tk_TypeCode: return TC_CORBA_TypeCode;
> 		case CORBA_tk_string: return TC_CORBA_string;
> 	}
> 
> 	return (CORBA_TypeCode) NULL;
> }
> 
> gpointer get_string ()
> {
> 	static void *_args[1];
> 
> 	static char *str = "Hello World!";
> 
> 	_args[0] = &str;
> 
> 	return _args;
> }
> 
> >> main.c
> #include <orbit/orbit.h>
> #include <stdio.h>
> 
> CORBA_ORB orb_init (char *orb_identifier, CORBA_Environment *ev);
> CORBA_TypeCode get_typecode (CORBA_TCKind kind);
> 
> int
> main (int argc, char* argv[])
> {
>    gpointer _args[1];
> 	CORBA_Environment *ev = NULL;
> 	CORBA_ORB orb;
> 	CORBA_Object echo;
> 	char *string =  "Hello from C";
> 	char ior[2048];
> 	FILE *echo_ref;
> 	int i;
> 
> 	ORBit_IArg arginfo[] = {
> 	{get_typecode (CORBA_tk_string), ORBit_I_ARG_IN, "input"}
> 	};
> 
> 	ORBit_IMethod imethod[] =
> 	{
> 		{{1, 1, arginfo, FALSE},
> 			{0, 0, NULL, FALSE},
> 			{0, 0, NULL, FALSE},
> 			get_typecode (CORBA_tk_void), "echoString", 10,
> 		0	}
> 	};
> 
> 	ORBit_IMethods methods = {1, 1, imethod, FALSE};
> 
> 	if (argc > 1)
> 		_args[0] = &argv[1];
> 	else
> 		_args[0] = &string;
> 
> 	echo_ref = fopen ("echo.ref", "r");
> 
> 	fread (&ior, sizeof(char), 2048, echo_ref);
> 
> 	fclose (echo_ref);
> 
> 	ev = CORBA_exception__alloc ();
> 
> 	CORBA_exception_init (ev);
> 
> 	orb = orb_init ("orbit-local-orb", ev);
> 
> 	echo = CORBA_ORB_string_to_object (orb, ior, ev);
> 
>    ORBit_c_stub_invoke(echo, &methods, 0, NULL, get_string (), NULL,
> 					   ev, 0, 4,
> 					   NULL);
> 
> 	CORBA_ORB_destroy(orb, ev);
> 
> 	CORBA_exception_free (ev);
> 
> 	CORBA_free (ev);
> 
> 	return 0;
> }
> 
> >> main.cs
> using System;
> using System.IO;
> using System.Runtime.InteropServices;
> 
> public struct IArg
> {
> 	public IntPtr typecode; //TypeCodes are extern in libORBit-2.so.0
> 	public long flags;
> 	public String name;
> };
> 
> public struct IArgs
> {
> 	public ulong _maximum, _length;
> 	public IArg[] _buffer;
> 	public bool _release;
> }
> 
> public struct IContexts
> {
> 	public ulong _maximum, _length;
> 	public string[] _buffer;
> 	public bool _release;
> }
> 
> public struct ITypes
> {
> 	public ulong _maximum, _length;
> 	public IntPtr[] _buffer; //TypeCode again
> 	public bool _release;
> }
> 
> public struct IMethod
> {
> 	public IArgs arguments;
> 	public IContexts contexts;
> 	public ITypes exceptions;
> 	public IntPtr ret; //TypeCode again
> 	public string name;
> 	public long name_len;
> 	public long flags;
> }
> 
> public struct IMethods
> {
> 	public ulong _maximum, _length;
> 	public IMethod[] _buffer;
> 	public bool _release;
> }
> 
> public class SimpleCorbaClient
> {
> 	[DllImport("libORBit-2.so.0")]
> 	public static extern IntPtr CORBA_exception__alloc ();
> 
> 	[DllImport("libORBit-2.so.0")]
> 	public static extern void CORBA_free (IntPtr ptr);
> 
> 	[DllImport("libORBit-2.so.0")]
> 	public static extern void CORBA_exception_free (IntPtr ev);
> 
> 	[DllImport("libORBit-2.so.0")]
> 	public static extern IntPtr CORBA_ORB_string_to_object (IntPtr orb, string ior, IntPtr ev);
> 
> 	[DllImport("libORBit-2.so.0")]
> 	public static extern void CORBA_ORB_destroy (IntPtr orb, IntPtr ev);
> 
> 	[DllImport("libORBit-2.so.0")]
> 	public static extern void ORBit_c_stub_invoke (IntPtr obj,
> 						       IMethods[] methods, 
> 						       long method_index,
> 						       IntPtr ret,
> 						       IntPtr args,
> 						       IntPtr ctx,
> 						       IntPtr ev,
> 						       long class_id,
> 						       long method_offset,
> 						       IntPtr skel_impl);
> 
> 	[DllImport("libglue.so")]
> 	public static extern IntPtr orb_init (string orb_identifier, IntPtr ev);
> 
> 	[DllImport("libglue.so")]
> 	public static extern IntPtr get_typecode (long kind);
> 
> 	[DllImport("libglue.so")]
> 	public static extern IntPtr get_string ();
> 
> 	static void Main()
> 	{
> 
> 		IArg[] arginfo = new IArg[1];
> 		IArgs args;
> 		IContexts contexts;
> 		ITypes types;
> 		IMethod[] imethod = new IMethod[1];
> 		IMethods[] imethods = new IMethods[1];
> 		IntPtr ev;
> 		IntPtr orb;
> 		IntPtr echo;
> 
> 		string ior;
> 		using (StreamReader iorFile = new StreamReader("echo.ref"))
> 		{
> 			ior = iorFile.ReadToEnd();
> 		}
> 
> 		arginfo[0].typecode = get_typecode (18);
> 		arginfo[0].flags = 32;
> 		arginfo[0].name = "input";
> 
> 		args._maximum = 1;
> 		args._length = 1;
> 		args._buffer = arginfo;
> 		args._release = false;
> 
> 		contexts._maximum = 0;
> 		contexts._length = 0;
> 		contexts._buffer = null;
> 		contexts._release = false;
> 
> 		types._maximum = 0;
> 		types._length = 0;
> 		types._buffer = null;
> 		types._release = false;
> 
> 		imethod[0].arguments = args;
> 		imethod[0].contexts = contexts;
> 		imethod[0].exceptions = types;
> 		imethod[0].ret = get_typecode (1);
> 		imethod[0].name = "echoString";
> 		imethod[0].name_len = 10;
> 		imethod[0].flags = 0;
> 
> 		imethods[0]._maximum = 1;
> 		imethods[0]._length = 1;
> 		imethods[0]._buffer = imethod;
> 		imethods[0]._release = false;
> 
> 		ev = CORBA_exception__alloc ();
> 
> 		orb = orb_init ("orbit-local-orb", ev);
> 
> 		echo = CORBA_ORB_string_to_object (orb, ior, ev);
> 
> 		ORBit_c_stub_invoke(echo, imethods, 0, IntPtr.Zero, get_string(), IntPtr.Zero,
> 					   ev, 0, 4,
> 					   IntPtr.Zero);
> 
> 		CORBA_ORB_destroy(orb, ev);
> 
> 		CORBA_exception_free (ev);
> 
> 		CORBA_free (ev);
> 	}
> }
> 
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list




More information about the Mono-devel-list mailing list