[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