swig + mono : C# example errors of not finding the library
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/SWIGExceptionHe开发者_运维技巧lper/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
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.
System.DllNotFoundException: example
It looks like it cannot find your unmanaged dll: "example".
You can specify what DLL the pinvoke signatures target in your interface file.
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.
精彩评论