[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