2

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

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

在 Linux 上,链接我的共享库不会链接其他共享库。使用 C++ 驱动程序,我在链接应用程序时指定另一个库,此时所有符号都已解析。但是,当我尝试从 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 之间的垫片。)

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

编辑:回答问题:

您确定可以在 LD_LIBRARY_PATH 环境变量中找到非托管 libexif-wrapper 吗?

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

4

2 回答 2

4

您应该在链接包装器库时指定依赖项,例如

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

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

于 2009-04-02T22:08:11.997 回答
2

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

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

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

于 2009-04-02T22:07:43.810 回答