【问题标题】:Linux, Mono, shared libs and unresolved symbolsLinux、Mono、共享库和未解析的符号
【发布时间】:2010-10-17 05:10:06
【问题描述】:

我有一个 shim 库(共享,C++),它调用另一个共享库 (libexif) 中的函数,并提供一个简单的 C# 接口用于平台调用调用。 (也就是说,一个 C# 程序使用 PInvoke 调用我的自定义共享库,该共享库又调用另一个共享库。)

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

在 Linux 上,链接我的共享库不会链接其他共享库。使用 C++ 驱动程序,我在链接 application 时指定另一个库,此时所有符号都已解析。但是,当我尝试从 C# 程序(使用单声道编译)调用我的共享库时,其他共享库中的符号无法解析。我尝试使用 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# 程序调用的,而是我的共享库中的一个函数调用了随后找不到的函数。 (谢谢 - 汉克)

【问题讨论】:

    标签: c# linux mono shared-libraries


    【解决方案1】:

    您应该在链接包装库时指定依赖项

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

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

    【讨论】:

    • 我今天使用 Code::Blocks 16.11 彻底测试了您的解决方案,但我仍然收到运行时错误 /usr/bin/mono: symbol lookup error: /home/venkat/DevelopmentX64/SmartCamXi_Hybrid_Linux/Debug/libDataServerLib64 .so:未定义符号:_Z15ciIPC_OpenMutexPKc
    【解决方案2】:

    我对你为什么需要 -lc 感到困惑,但也许那是 Mono 的奇怪之处......

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

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

    【讨论】:

    • 是的,谢谢。将 -lexif 添加到我的 shim 库的链接命令可以解决问题。结果证明 -lc 不是必需的。那是我复制的一个示例的一部分(并且我盲目地复制了它。)消除它似乎对我的 C++ 测试应用程序和我的 C# 测试应用程序都没有造成任何困难。
    猜你喜欢
    • 1970-01-01
    • 2014-03-06
    • 2011-02-28
    • 2010-12-09
    • 2012-06-13
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    相关资源
    最近更新 更多