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 <[email protected]> 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 > > > _______________________________________________ Mono-list maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-list
