[Gtk-sharp-list] Embedding Gtk-Sharp Programs into C

Pyroman[FO] pyroman@ninjapanda.org
Mon, 26 Jul 2004 13:59:51 -0400


This worked like a charm, for anybody wanting to know the actual code,
here's my example, MonoTest.  It creates a Frame in C, then passes the
pointer to a C# function, which creates a C# frame and manipulates it.
These changes are reflected in the original C frame.

Thanks Mikkel, this'll do what I need it to.  However I was still having
problems getting it linked when it was a C++ program using GtkMM.  I
kept getting undefined reference errors for every mono function I called
in C++ and GtkMM, when the exact same code using C and GTK+ worked fine.

monotest.c >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <gtk/gtk.h>
#include <mono/jit/jit.h>
#include <string.h>
#include <stdlib.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/environment.h>
int main(int argc, char *argv[])  {

	GtkWidget *window;

	gtk_init (&argc, &argv);

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);	

	MonoDomain *domain;
	MonoAssembly *assembly;
	MonoClass *monoclass;
	MonoMethodDesc *desc;
	MonoMethod *method,*m;
	MonoImage *image;
	MonoObject *obj;
	GtkWidget *widget;
	gpointer iter;

	printf("mono jit init\n");
	domain = mono_jit_init("monotest.exe");
	if (!domain) printf("FAIL\n");
	printf("mono thread attach\n");
	mono_thread_attach(domain);
	printf("mono domain assembly open\n");
	assembly = mono_domain_assembly_open(domain, "monotest.exe");
	if (!assembly) printf("FAIL\n");
	printf("mono jit exec\n");
	mono_jit_exec(domain,assembly,argc-1,argv+1);
	printf("mono assembly get image\n");
	image = mono_assembly_get_image(assembly);
	if (!image) printf("FAIL\n");
	printf("mono class from name\n");
	monoclass = mono_class_from_name (image, "MonoTestSpace", "MonoTest");
	if (!monoclass) printf("FAIL\n");
	printf("get method\n");
	iter = NULL;
	while ((m = mono_class_get_methods (monoclass, &iter)))
		if (strcmp (mono_method_get_name (m), "Test") == 0)
			method = m;		
	if (!method) printf("FAIL\n");

	printf("mono object new\n");
	obj = mono_object_new(domain,monoclass);
	if (!obj) printf("FAIL\n");
	printf("mono runtime object init\n");
	mono_runtime_object_init(obj);
	gpointer args[1];
	widget = gtk_frame_new(0);
	args[0] = &widget; 	
	printf("mono runtime invoke\n");
	mono_runtime_invoke(method,obj,args,NULL);
	gtk_container_add(GTK_CONTAINER(window),widget);

	gtk_widget_show_all(window);

	gtk_main ();
return 0;
}

monotest.cs >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
namespace MonoTestSpace
{
	using Gtk;
	using GtkSharp;
	using System;
	class MonoTest
	{
		public void Test (IntPtr raw)
		{	
			Gtk.Frame frame = new Gtk.Frame(raw);
			frame.Label = "In C#";
		}
		static void Main()
		{
		}
	}
}

Allen Cook


Mikkel Kruse Johnsen wrote:
> Hi Pyroman
> 
> I don't think that will work, but try. I would make the GtkFrame in C
> like this and have C# add to it.
> 
> GtkFrame *frame;
> 
> frame = gtk_frame_new ();
> args[0] = &frame;
> mono_runtime_invoke (method, object, args, NULL);
> 
> and in C# do:
> 
> namespace TestApp
> {
> 	class Plugin : Gtk.Frame
> 	{
> 		public Plugin (IntPtr raw) : base(raw)	
> 		{
> 			this.Add (new Gtk.Button("Hello World");
> 		}
> 	}
> 
> 	class Test
> 	{
> 		public void Init (IntPtr raw)
> 		{
> 			new Plugin (raw);
> 		}
> 	}
> }
> 
> /Mikkel
> 
> On Fri, 2004-07-23 at 16:12, Pyroman[FO] wrote:
> 
>>So if I create in C#
>>
>>Gtk.Frame frame;
>>
>>Then in the Test.Init function do
>>
>>raw = frame
>>
>>Then resulting C program can then use widget as a valid GtkWidget pointer?
>>
>>Allen Cook
>>
>>Mikkel Kruse Johnsen wrote:
>>
>>>Hi Pyroman
>>>
>>>Yes, it is possible.
>>>
>>>I'm myself embedding bonobo componets written in gtk-sharp (C#) into my
>>>C program. It is where possible to return Gtk.Widget, I don't do that
>>>myself, but im passing a Gtk.Container to the C# code and the adding
>>>stuff to that.
>>>
>>>Just do this in the C program:
>>>
>>>	domain = mono_jit_init (PACKAGE);
>>>	mono_config_parse ("/etc/mono/machine.config");
>>>	mono_config_parse ("/etc/mono/config");
>>>	mono_thread_attach (domain);
>>>
>>>and then:
>>>
>>>	MonoDomain 	 	 		*domain;
>>>	MonoAssembly 	 		*assembly;	
>>>	MonoClass				*class;
>>>	MonoImage				*image;
>>>	MonoMethod	 	*method;
>>>	MonoObject 		*object;
>>>	MonoMethodDesc 	*desc;
>>>	gpointer 		 args[1];
>>>	GtkWidget	*widget;
>>>
>>>	domain = mono_domain_get ();
>>>	assembly = mono_domain_assembly_open (domain, "test.dll");
>>>	image = mono_assembly_get_image (assembly);
>>>	class = mono_class_from_name (image, "TestApp", "Test");
>>>	desc = mono_method_desc_new ("TestApp.Test:Init", TRUE);
>>>	method = mono_method_desc_search_in_class (desc, class);
>>>	mono_method_desc_free (desc);
>>>	object = mono_object_new (domain, class);
>>>	mono_runtime_object_init (object);
>>>	args[0] = &widget;
>>>	mono_runtime_invoke (method, object, args, NULL);
>>>
>>>C#
>>>
>>>namespace TestApp
>>>{
>>>	class Test
>>>	{
>>>		public void Init (IntPtr raw)
>>>		{	
>>>		}
>>>	}
>>>}
>>>
>>>
>>>This is just a rough paste, but should work somewhat.
>>>
>>>/Mikkel
>>>
>>>On Thu, 2004-07-22 at 19:29, Pyroman[FO] wrote:
>>>
>>>
>>>>I was wondering if there was a way to embed a Gtk-Sharp application in a 
>>>>C program.  I know you can do this with Mono, however what I'm worried 
>>>>about is the ability to return Gtk Widgets, Containers, ect. to the 
>>>>parent C program and use them with GTK or GTKmm code.  Our program has a 
>>>>plugin structure, and we call the plugin to return the main GTK frame 
>>>>for the plugin, which we then display in the parent program.  I am 
>>>>looking for a way to embed the Mono runtime and use mono plugins for 
>>>>this.  Is it possible?
>>>>
>>>>Allen Cook
>>>>_______________________________________________
>>>>Gtk-sharp-list maillist  -  Gtk-sharp-list@lists.ximian.com
>>>>http://lists.ximian.com/mailman/listinfo/gtk-sharp-lis
>>>
>>>t
>>
>>_______________________________________________
>>Gtk-sharp-list maillist  -  Gtk-sharp-list@lists.ximian.com
>>http://lists.ximian.com/mailman/listinfo/gtk-sharp-lis
> 
> t