我在Mac OS X 10.6.4上使用swig 2.0.1 + mono 2.6 / 2.8。
整体构建没问题,C#示例的构建也没问题。问题是,当我运行示例(mono runme.exe)时,我总是得到以下错误。
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
好像它找不到示例库,但生成的库是libexample.so。
这是生成libexample.so
的库的源代码double Foo = 3.0;
int gcd(int x, int y) {
...
}
这是使用libexample.so的C#源。
using System;
public class runme
{
static void Main()
{
int x = 42;
int y = 105;
int g = example.gcd(x,y);
...
}
}
这是使用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;
}
}
}
这是运行以获取库和执行的命令。
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
可能有什么问题?应该怎么做让单声道知道libexample.so?
我可以使用“swig -csharp -dllimport”libexample.so“example.i”,但我得到了相同的结果。 我附上examplePINVOKE.cs。
正如本post所述,我运行了“MONO_LOG_LEVEL = debug mono runme.exe”。消息说,即使文件退出,mono也找不到./libexample.so。
Mono: DllImport loading library: './libexample.so'. Mono: DllImport error loading library '(null)'.
我可以在swig / Examples中更改Makefile来解决这个问题。
CFLAGS = -arch i386
答案 0 :(得分:2)
这可能是由于库被编译为64位而引起的。 “(null)”表示Mono无法获取此错误的错误消息。您可以通过设置适当的编译标志来解决此问题。例如:
./configure CFLAGS="-O -arch i386" CXXFLAGS="-O -arch i386" LDFLAGS="-arch i386" --disable-dependency-tracking
您也可以通过使用Mono的实验性64位支持来解决这个问题,但我从未这样做过,所以我不确定。
答案 1 :(得分:1)
System.DllNotFoundException:example
看起来它无法找到你的非托管dll:“example”。
答案 2 :(得分:1)
您可以指定pinvoke签名在接口文件中定位的DLL。
答案 3 :(得分:1)
您还应该确保该文件位于动态链接器搜索路径中,即在MacOS上:
export DYLD_FALLBACK_LIBRARY_PATH="/directory/with/your/dylb/file:$DYLD_FALLBACK_LIBRARY_PATH"
顺便说一下,MacOS通常会期望一个.dylib文件,而不是.so文件。