首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby,ffi和自定义C库

问Ruby,ffi和自定义C库
EN

Stack Overflow用户
提问于 2017-12-13 15:16:37
回答 1查看 354关注 0票数 1

我正在尝试创建一个定制的C库,我可以使用FFI从Ruby调用。我的库将用我自己的代码包装某些libtiff函数,由此产生的更高级别的函数将通过FFI接口从Ruby内部调用。

我已经用C语言编写了测试代码,它成功地编译成一个.so文件。我已经通过FFI将相同的代码插入Ruby中,并且可以成功地从ruby代码调用简单的函数。

但是,当我在C库代码中包含libtiff并定义一个使用某些libtiff例程的函数时,ruby代码会在运行时抛出类似于下面的错误。

代码语言:javascript
复制
/usr/bin/ruby: symbol lookup error: /<path_to_lib>/libtiffconverter.so: undefined symbol: TIFFOpen

我的猜测是,这与编译器/链接器所做的事情有关。我对C很生疏..。在15+的几年里,我都没碰过它,我也不知道该怎么办才能解决这个问题。我正在使用代码::块IDE,并将我的代码放在一个动态库项目中。只要我不包括libtiff,一切都如预期的那样工作。一旦我做了..。虽然代码会编译,但我会得到libtiff.so中任何内容的符号查找错误。

下面是生成上述错误的测试库模块代码:

代码语言:javascript
复制
#include "tiffio.h"

int AddInt(int i1, int i2)
{
    return i1 + i2;
}

void ConvertTIFF()
{
    TIFF* tif = TIFFOpen("test0.tiff", "r");
    if (tif) {
        uint32 imagelength;
        tdata_t buf;
        uint32 row;

        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength);
        buf = _TIFFmalloc(TIFFScanlineSize(tif));
        for (row = 0; row < imagelength; row++)
            TIFFReadScanline(tif, buf, row, 0);
        _TIFFfree(buf);
        TIFFClose(tif);
    }
}

下面是编译器命令

代码语言:javascript
复制
gcc -Wall -O2 -fPIC -I/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu -c /<path_to_source>/main.c -o obj/Release/main.o
g++ -shared  obj/Release/main.o  -o bin/Release/libtiffconverter.so -s

AddInt()通过FFI从红宝石打电话来,工作很好。ConvertTIFF()没有。任何帮助都是非常感谢的。

更新1:

以下是我的自定义库的ldd输出:

代码语言:javascript
复制
bridge:~/tmp/tmp$ ldd libtiffconverter.so
    linux-vdso.so.1 =>  (0x00007ffd20db8000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4c9a84e000)
    /lib64/ld-linux-x86-64.so.2 (0x000055a601577000)

更新2:

下面是ldd的输出,现在一切都正常了:

代码语言:javascript
复制
bridge:~/tmp/tmp$ ldd libtiffconverter.so 
    linux-vdso.so.1 =>  (0x00007ffff4db7000)
    libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5 (0x00007fabcbea4000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fabcbacb000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fabcb8a8000)
    libjbig.so.0 => /usr/lib/x86_64-linux-gnu/libjbig.so.0 (0x00007fabcb69a000)
    libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007fabcb441000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fabcb226000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fabcaf1d000)
    /lib64/ld-linux-x86-64.so.2 (0x000056320a73f000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fabcad19000)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-13 15:28:13

问题

/usr/bin/ruby: symbol lookup error: /<path_to_lib>/libtiffconverter.so: undefined symbol: TIFFOpen

找不到您的TIFFOpen()所使用的函数ConvertTIFF()。此函数属于LibTIFF库。您需要将您的项目链接到此库。

解决方案:链接到LibTIFF

将选项-ltiff添加到上面的g++行,即:

代码语言:javascript
复制
g++ -shared  obj/Release/main.o  -o bin/Release/libtiffconverter.so -s -ltiff

您可以这样检查刚刚生成的libtiffconverter.so是否实际上依赖于LibTIFF库(它应该如此):

代码语言:javascript
复制
ldd libtiffconverter.so | grep  libtiff

下面是上面命令的示例输出:

代码语言:javascript
复制
libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5 (0x00007fda361a8000)

您还可能需要将-L选项添加到上面的g++行,然后是您的libtiff.so所在的目录。为了获得它的位置,您可以执行以下操作:

代码语言:javascript
复制
find / -name 'libtiff*'
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47796477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档