tags:

views:

84

answers:

4

I use swig 2.0.1 + mono 2.6/2.8 on Mac OS X 10.6.4.

The overall build is OK, and the build of the C# examples is also OK. The problem is that when I run the example (mono runme.exe), I always get the following errors.

Unhandled Exception: System.TypeInitializationException: An exception was thrown by the type initializer for examplePINVOKE ---> System.TypeInitializationException: An exception was thrown by the type initializer for SWIGExceptionHelper ---> System.DllNotFoundException: example
  at (wrapper managed-to-native) examplePINVOKE/SWIGExceptionHelper:SWIGRegisterExceptionCallbacks_example (examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate,examplePINVOKE/SWIGExceptionHelper/ExceptionDelegate)
  at examplePINVOKE+SWIGExceptionHelper..cctor () [0x00000] in :0 
  --- End of inner exception stack trace ---
  at examplePINVOKE..cctor () [0x00000] in :0 
  --- End of inner exception stack trace ---
  at example.gcd (Int32 x, Int32 y) [0x00000] in :0 
  at runme.Main () [0x00000] in :0 

It seems like that it doesn't find the example library, but the generated library is libexample.so.

This is the source of the library to generate libexample.so

double Foo = 3.0;
int gcd(int x, int y) {
  ...
}

This is the C# source for using libexample.so.

using System;

public class runme
{
    static void Main() 
    {
        int x = 42;
        int y = 105;
        int g = example.gcd(x,y);
        ...
    }
}

This is the wrapper function that is generated with SWIG.

/* ----------------------------------------------------------------------------
 * This file was automatically generated by SWIG (http://www.swig.org).
 * Version 2.0.1
 *
 * Do not make changes to this file unless you know what you are doing--modify
 * the SWIG interface file instead.
 * ----------------------------------------------------------------------------- */
using System;
using System.Runtime.InteropServices;

public class example {
  public static int gcd(int x, int y) {
    int ret = examplePINVOKE.gcd(x, y);
    return ret;
  }

  public static double Foo {
    set {
      examplePINVOKE.Foo_set(value);
    } 
    get {
      double ret = examplePINVOKE.Foo_get();
      return ret;
    } 
  }
}

This is the command to run to get the library and the execution.

gcc -c    example.c example_wrap.c 
cc -bundle -undefined suppress -flat_namespace  example.o  example_wrap.o   -o libexample.so
make -f ../../Makefile CSHARPSRCS='*.cs' CSHARPFLAGS='-nologo -out:runme.exe' csharp_compile
gmcs -nologo -out:runme.exe *.cs

What might be wrong? What should be done to let mono know about the libexample.so?

ADDED

I could use "swig -csharp -dllimport "libexample.so" example.i", but I got the same result. I attach the examplePINVOKE.cs.

As is written in this post, I ran "MONO_LOG_LEVEL=debug mono runme.exe". The message says mono can't find the ./libexample.so even though the file exits.

Mono: DllImport loading library: './libexample.so'.
Mono: DllImport error loading library '(null)'.

SOLUTION

I could change Makefile in swig/Examples to solve this issue.

CFLAGS     = -arch i386
+1  A: 

System.DllNotFoundException: example

It looks like it cannot find your unmanaged dll: "example".

jpobst
@jpobst : Thanks for the answer, I elaborated the question more.
prosseek
+1  A: 

You can specify what DLL the pinvoke signatures target in your interface file.

iterationx
@iterationx : Could you give me an example for the interface file?
prosseek
@proseek Just use the -dllimport directive when you invoke swig, as per the documentation, http://swig.org/Doc2.0/SWIGDocumentation.html swig -dllimport "mydll.dll" swig.i
iterationx
@iterationx : The swig on my Mac doesn't have the -dllimport option. Any more hints?
prosseek
@proseek can you elaborate on what you are trying to achieve, i suspect there might be an easier method. Can you just open up the generated c++ code and manually put in your lib.so?
iterationx
@iterationx : swig -csharp -dllimport works, even though the result is the same. I added to the original post. Thanks.
prosseek
@proseek, try making main public
iterationx
+1  A: 

You should also ensure the file is in the dynamic linker search path, i.e. on MacOS:

export DYLD_FALLBACK_LIBRARY_PATH="/directory/with/your/dylb/file:$DYLD_FALLBACK_LIBRARY_PATH"

BTW, MacOS one would generally expect a .dylib file, not a .so file.

mhutch
@mhutch : I added the environment variable, but it doesn't seem to work. For .so, the swig generates .so not .dylib as follows "cc -bundle -undefined suppress -flat_namespace example.o example_wrap.o -o libexample.so". Thanks for the help.
prosseek
@mhutch : I see that the variable should be setup to solve other problems. - http://stackoverflow.com/questions/3918410/system-entrypointnotfoundexception-error-in-swig-on-mono-2-8
prosseek
+1  A: 

This is likely caused by the library being compiled as 64-bit. The "(null)" means that Mono was not able to obtain the error message of this error. You can fix this by setting the appropriate compile flags. For instance:

./configure CFLAGS="-O -arch i386" CXXFLAGS="-O -arch i386" LDFLAGS="-arch i386" --disable-dependency-tracking

You may also be able to fix this by using Mono's experimental 64-bit support but I have never done that so am not sure.

Tristan
@Tristan : Yes, I recompiled the library with -arch i386 option, and it works fine. Thanks!
prosseek