我正在尝试创建一个自定义的c库,我可以使用ffi从ruby调用它。我的库将用自己的代码包装某些libtiff函数,生成的高级函数将通过ffi接口从ruby内部调用。
我用C编写了测试代码,它可以成功地编译成.so文件。我已经通过ffi将同样的代码插入到ruby中,并且可以成功地从ruby代码调用简单的函数。
但是,当我在c库代码中包含libtiff并定义一个使用libtiff例程的函数时,ruby代码在运行时抛出类似于以下的错误。
/usr/bin/ruby: symbol lookup error: /<path_to_lib>/libtiffconverter.so: undefined symbol: TIFFOpen
我猜这与编译器/链接器的工作方式有关。我对C很生疏…已经15年多没碰过了,我也不知道该怎么解决这个问题。我正在使用,代码::块IDE,并将我的代码放在动态库项目中。只要我不包括libtiff,一切都按预期进行。一旦我做了…尽管代码是编译的,但libtiff.so中的任何内容都会出现符号查找错误。
下面是生成上述错误的测试库模块代码:
#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);
}
}
以下是编译器命令
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从ruby调用,工作正常。ConvertTIFF()
没有。任何帮助都非常感谢。更新1:
下面是我的自定义库的ldd输出:
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输出,现在一切正常:
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)
最佳答案
问题/usr/bin/ruby: symbol lookup error: /<path_to_lib>/libtiffconverter.so: undefined symbol: TIFFOpen
找不到您的TIFFOpen()
使用的函数ConvertTIFF()
。此函数属于libtiff库。您需要将项目链接到此库。
解决方案:链接libtiff
将选项-ltiff
添加到上面的g++
行,即:
g++ -shared obj/Release/main.o -o bin/Release/libtiffconverter.so -s -ltiff
您可以通过以下方式检查您刚刚生成的
libtiffconverter.so
是否实际依赖于libtiff库(它应该):ldd libtiffconverter.so | grep libtiff
下面是上面命令的输出示例:
libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5 (0x00007fda361a8000)
您可能还需要将
-L
选项添加到上面的g++
行,然后是libtiff.so
所在的目录。要获取其位置,可以执行以下操作:find / -name 'libtiff*'
关于c - Ruby,ffi和自定义C库,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47796477/