[Mono-list] Create a shared library
Matt Calder
mvcalder at gmail.com
Thu Oct 28 16:20:55 EDT 2010
Oops,
I forgot to include:
//////////// CallMe.cs /////////////////
using System;
namespace CallMe
{
public class CallMe
{
public static int Call(int i)
{
return i + 1;
}
}
}
On Thu, Oct 28, 2010 at 4:19 PM, Matt Calder <mvcalder at gmail.com> wrote:
> 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