Linux,Mono,共享库和未解析的符号

时间:2009-04-02 19:53:33

标签: c# linux mono shared-libraries

我有一个shim库(共享,C ++),它调用另一个共享库(libexif)中的函数,并为C#for Platform Invoke调用提供一个简单的接口。 (也就是说,C#程序使用PInvoke来调用我的自定义共享库,而后者又调用另一个共享库。)

在Windows中,当我的自定义库链接时,我的自定义共享库链接到共享库,当C#应用程序执行时,所有符号都会被解析。

在Linux上,链接我的共享库不会链接其他共享库。使用C ++驱动程序时,我会在应用程序链接时指定其他库,此时所有符号都会被解析。但是,当我尝试从C#程序调用我的共享库(使用mono编译)时,其他共享库中的符号无法解析。我已经尝试使用MONO_PATH变量来指定其他库,但似乎没有什么区别。我也尝试在DLLimport语句中指定未解析的函数,但这似乎也无济于事。

如何指定C#代码不直接调用的共享库,以便mono / cli在运行时找到它?

我使用以下命令构建共享库:

g++ -fPIC -g -c -Wall  libexif-wrapper.cpp
g++ -shared -Wl,-soname,libexif-wrapper.so.1     -o libexif-wrapper.so.1.0.1 libexif-wrapper.o -lc
ar rcs libexif-wrapper.a libexif-wrapper.so.1

以下命令行来编译我的C#驱动程序:

mcs -unsafe -define:LINUX Test-libexif-wrapper.cs

执行时,我收到一条错误,即找不到我的共享库使用的符号:

/usr/bin/cli: symbol lookup error: ../../../C/libexif-wrapper/libexif-wrapper/libexif-wrapper.so.1: undefined symbol: exif_data_new_from_file

(libexif-wrapper是我的共享库,它充当C#应用程序和libexif之间的垫片。)

我无法弄清楚如何解决这个问题。任何建议将不胜感激。

编辑:回答问题:

  你确定不受管理吗?   libexif-wrapper可以在   LD_LIBRARY_PATH环境变量?

事实上并非如此。我已经在DLLImport中制作了直接指向它的路径。运行时查找它,因为它在上面的错误消息中报告了它的路径。此外,缺少的符号不会被C#程序调用,而是我的共享库中的一个函数调用当时未找到的函数。 (谢谢 - 汉克)

2 个答案:

答案 0 :(得分:3)

您应该在链接包装库时指定依赖关系,如

g++ -shared -Wl,-soname,libexif-wrapper.so.1 -o libexif-wrapper.so.1.0.1 libexif-wrapper.o -lc -lexif

当你这样做时,动态链接器知道libexif-wrapper依赖于libexif,它可以在加载时解析符号。

答案 1 :(得分:2)

我对你为什么需要-lc感到困惑,但也许这就是单声道奇怪......

如果将-lexif添加到链接命令,它是否有效?您似乎正在使用未定义的符号创建共享库,但不是说这些符号应该来自哪里。这实际上有时是有用的 - 比如说,创建一个插件,使用一个符号,该符号应该由加载它的应用程序提供 - 但不是你想要的;我不知道libdl(或者Mono如何加载库,也许它有自己的实现)会知道它需要加载libexif.so以便在你的库中使用。

希望您不必做一些可怕的事情,例如将libexif.so添加到存档...