gpt4 book ai didi

c - Ruby、ffi 和自定义 C 库

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:37:00 28 4
gpt4 key购买 nike

我正在尝试创建一个可以使用 FFI 从 Ruby 调用的自定义 C 库。我的库将用我自己的代码包装某些 libtiff 函数,生成的更高级别的函数将通过 FFI 接口(interface)从 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 年多没有碰过它了,而且我不确定到底该怎么做才能解决这个问题。我正在使用 Code::Blocks 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com