[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