[Mono-list] Create a shared library

Matt Calder mvcalder at gmail.com
Thu Oct 28 16:19:04 EDT 2010


Thanks for all the replies.

Jon's answer turned out to be the one I was looking for. In the
interest of putting it into the record, here is a very short example
that compiled for me and I could call the resulting shared object from
R. I assume calling from python will be as easy. There is no error
checking and no cleanup in the code, I guess the API documentation
link http://go-mono.com/docs/index.aspx?tlink=root:/embed will tell
how / when to do that. The code is written so as to compile as both an
executable and a library. R has a particular calling convention for
calling into shared libraries, that is why RCallMe is the way it is.

Hats off to the mono team. I was able to write, compile, and run this
in less than 30 minutes based on the instructions here:
http://www.mono-project.com/Embedding_Mono. This really opens a lot of
doors for us in terms of sharing C# code across our group.

Matt

////////////// makefile //////////////

CFLAGS=`pkg-config --cflags mono-2`
LDFLAGS=`pkg-config --libs mono-2`

all: main lib

main: callme.cc
	gcc -o callme callme.cc $(CFLAGS) $(LDFLAGS)

lib: callme.cc
	gcc --shared -fPIC -o callme.so callme.cc -D LIB $(CFLAGS) $(LDFLAGS)


////////// callme.cc /////////
#include <iostream>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>

int CallMe(int i);

extern "C" {
  void RCallMe(int *i);
}

void RCallMe(int *i)
{
  *i = CallMe(*i);
}

#ifndef LIB
int main(int argc, char** argv)
{
  int ans = CallMe(7);
  std::cout << "ans = " << ans << "\n";
}
#endif

int CallMe(int i)
{
  MonoDomain *domain;

  domain = mono_jit_init("domain_name");

  MonoAssembly *assembly = mono_domain_assembly_open(domain, "CallMe.dll");

  MonoImage *image = mono_assembly_get_image(assembly);

  MonoMethodDesc *desc = mono_method_desc_new("CallMe.CallMe:Call", true);

  MonoMethod *method = mono_method_desc_search_in_image(desc, image);

  void* arg = (void *) &i;
  MonoObject* ans = mono_runtime_invoke(method, NULL, &arg, NULL);
  int j = *((int*) mono_object_unbox(ans));
  mono_jit_cleanup(domain);
  return j;
}

/////////////////////////////////////////////////////



On Thu, Oct 28, 2010 at 3:03 PM, Jonathan Pryor <jonpryor at vt.edu> wrote:
> On Thu, 2010-10-28 at 12:07 -0400, Matt Calder wrote:
>> Is it possible to compile a C# library, using mono, into a native
>> shared library on a linux system? I would like to then
>> call that shared library from other languages (python and R).
>
> Short answer: No.
>
> Workaround answer: you can create a normal C shared library which uses
> Mono's embedding interface, and use this native shared library as "glue"
> between your "host" environment (R, Python) to managed code, using the
> embedding APIs to load assemblies, create instances of types, and invoke
> methods.
>
> See also:
>
>        http://www.mono-project.com/Embedding_Mono
>        http://www.mono-project.com/Scripting_With_Mono
>        http://www.go-mono.com/docs/index.aspx?tlink=root:/embed
>
> Once upon a time there was a `cilc` program that would attempt to
> automate some of this for you, generating a GObject-like wrapper for a
> set of managed types.  Unfortunately, it was long unmaintained and was
> removed from Mono 2.8, but the sources may be of some use to you:
>
>        http://github.com/mono/mono/tree/mono-2-6/mcs/tools/cilc/
>
>  - Jon
>
>
>


More information about the Mono-list mailing list