[Mono-list] AppDomain

Daniel Lopez daniel@rawbyte.com
Mon, 24 Feb 2003 10:01:51 -0800

Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


I am looking for the correct way to call a method in a transparent proxy
from the C side of mono. When I create an object in a different AppDomain
and call it from C# everything is fine, but when I do it from C, it gets
executed in the same domain.
I attach some sample code to demonstrate what I mean.

In c# the result of compiling and running test.exe:
mcs test.cs /r:System.Web
mono test.exe

Main AppDomain: test.exe
Process request AppDomain: 56ca2e66

And compiling and running test.c
mcs test.cs /r:System.Web /target:library
cp test.dll /usr/lib  (or somewhere where it will be picked up from the path)
gcc -o test test.c pkg-config --cflags --libs mono -lm

Main Domain: testing
Process request AppDomain: testing

So what is the correct way of invoking the method so it will be executed in
the other domain? I tried every method I could think of with no luck.

Best regards


Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test.c"

#include <mono/jit/jit.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/debug-helpers.h>

main(int argc, char* argv[]) {
  MonoMethodDesc *desc;
  MonoClass *class, *klass;
  MonoMethod *method;
  MonoAssembly *assembly;
  MonoAssemblyName aname;
  MonoObject *sampleApplicationHost;
  MonoDomain *domain;
  gpointer params[2];
  int i;

  domain = mono_jit_init ("testing");
  aname.name = "test.dll";
  /* Specifying NULL base dir means it will look in path */
  if ((assembly = (MonoAssembly *)mono_assembly_load (&aname, NULL, NULL)) == NULL) {
    printf ("Could not find test.dll\n");
  class = mono_class_from_name (assembly->image, "", "SampleApplicationHost");
  if (class == NULL) {
    printf ("Could not find class");
  domain->entry_assembly = assembly;
  domain->setup->application_base = mono_string_new (domain, "/a");
  domain->setup->configuration_file = mono_string_new (domain, "/a.config");
  desc = mono_method_desc_new ("::CreateApplicationHost(string,string)", 0);
  method = mono_method_desc_search_in_class (desc, class);
  params[0] = mono_string_new (domain, "/a"); 
  params[1] = mono_string_new (domain, "/b"); 
  // What gets returned is a TransparentProxy
  sampleApplicationHost = mono_runtime_invoke (method, NULL, params, NULL);
  desc = mono_method_desc_new ("::ProcessRequest()", 0);  
  // I also tried 
  // processRequestMethod = mono_method_desc_search_in_class (mono_method_desc_new ("::ProcessRequest()", 0), class);
  klass = ((MonoTransparentProxy *)sampleApplicationHost)->klass;
  for (i = 0; i < klass->vtable_size; ++i) {
    if (!strcmp(klass->vtable[i]->name,"ProcessRequest")) break;
  printf("Main Domain: %s\n", mono_domain_get()->friendly_name);
  mono_runtime_invoke (klass->vtable[i], sampleApplicationHost, NULL, NULL);

Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test.cs"

using System;
using System.Web.Hosting;
//using Mono.ASPNET;

public class SampleApplicationHost : MarshalByRefObject
  public static object CreateApplicationHost (string virtualPath, string baseDirectory)
      return ApplicationHost.CreateApplicationHost (typeof (SampleApplicationHost), virtualPath, baseDirectory);

  public void ProcessRequest ()
      Console.WriteLine("Process request AppDomain: " + AppDomain.CurrentDomain.FriendlyName);

class Mono {
  static void Main() {
    SampleApplicationHost a = SampleApplicationHost.CreateApplicationHost("/b","/a") as SampleApplicationHost;
    Console.WriteLine("Main AppDomain: " + AppDomain.CurrentDomain.FriendlyName);