C++ 程序在两台不同的机器上编译。共享库在一个上正常工作。另一方面,类方法返回 NULL

标签 c++ c linux g++ openbabel

我正在尝试使用 openbabel 库编写一些程序,其中一个是从 sdf 文件中提取数据的简单程序。但是我拥有的 FormatFromExt 功能之一无法正常工作。无论我传递什么输入参数,函数调用都会返回 NULL。

OpenBabel::OBFormat *inputFormat = conv.FormatFromExt(argv[1]);
// This method fails, returns NULL ^^
if (!inputFormat || !conv.SetInFormat(inputFormat)) {
  char buf[256];
  sprintf(buf, "Could not find input format for file: %s", inputFormat);
  cerr << buf << endl;
  exit(0);
}

该类的其他方法 OBConversion 也返回 NULL,例如 SetInfFormatFindFormatRead

我已经验证 argv[1] 确实包含输入文件的路径,并且该文件具有 openbabel 库的有效扩展名。我还包括所有必要的头文件。在一台机器上,这段代码可以完美运行。另一方面,这些方法失败了。该程序在两者上都能完美编译。什么会导致这样的事情发生?

我使用的 openbabel 库是共享对象文件。

最佳答案

好的,所以这似乎是配置错误。基本上,它似乎在寻找 .so 文件,但在远程计算机上找不到任何文件。

那么让我们从两条轨迹的 fork 处开始观察。不难找到,因为它基本上位于失败跟踪的末尾。首先,让我们看一下有效的方法:

openat(AT_FDCWD, "/usr/local/lib/openbabel/2.3.2", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
brk(0x1199000)                          = 0x1199000
getdents(5, /* 112 entries */, 32768)   = 4200
getdents(5, /* 0 entries */, 32768)     = 0
close(5)                                = 0
futex(0x7f7fbacf90b0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
open("/usr/local/lib/openbabel/2.3.2/castepformat.so", O_RDONLY|O_CLOEXEC) = 5
read(5, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340.\0\0\0\0\0\0"..., 832) = 832
fstat(5, {st_mode=S_IFREG|0644, st_size=521866, ...}) = 0
mmap(NULL, 2126352, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7f7fba3db000
mprotect(0x7f7fba3e2000, 2093056, PROT_NONE) = 0
mmap(0x7f7fba5e1000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x6000) = 0x7f7fba5e1000
close(5)                                = 0
mprotect(0x7f7fba5e1000, 4096, PROT_READ) = 0
open("/usr/local/lib/openbabel/2.3.2/xedformat.so", O_RDONLY|O_CLOEXEC) = 5
read(5, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260'\0\0\0\0\0\0"..., 832) = 832
fstat(5, {st_mode=S_IFREG|0644, st_size=432606, ...}) = 0
mmap(NULL, 2118032, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7f7fba1d5000
mprotect(0x7f7fba1da000, 2093056, PROT_NONE) = 0
mmap(0x7f7fba3d9000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x4000) = 0x7f7fba3d9000
close(5)                                = 0
mprotect(0x7f7fba3d9000, 4096, PROT_READ) = 0
open("/usr/local/lib/openbabel/2.3.2/PQSformat.so", O_RDONLY|O_CLOEXEC) = 5

它打开目录 /usr/local/lib/openbabel/2.3.2,然后读取其中的所有条目。有 4200 字节的条目。然后它依次加载一堆 .so 文件(共享库)。这些大概是它在 /usr/local/lib/openbabel/2.3.2 中找到的。

好的,现在让我们看看失败的那个:

open("/tools/cluster/6.2/openbabel/2.3.2/lib/openbabel", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
fcntl(5, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
brk(0x1dd6000)                          = 0x1dd6000
getdents(5, /* 3 entries */, 32768)     = 80
getdents(5, /* 0 entries */, 32768)     = 0
brk(0x1dce000)                          = 0x1dce000
close(5)                                = 0
write(2, "Could not find input format for "..., 76Could not find input format for file: files/Compound_014725001_014750000.sdf) = 76

它打开 /tools/cluster/6.2/openbabel/2.3.2/lib/openbabel。然后它只读取 80 个字节的条目,大概是因为该目录是空的或接近空的。然后它会立即打印错误消息。

看来配置指向错误的目录,或者该目录从未填充所有 .so 文件。请注意,它发现 Compound_014725001_014750000.sdf 在这两种情况下都很好。如果你从我开始引用的地方看上面的几行,你可以看到打开的系统调用。

关于C++ 程序在两台不同的机器上编译。共享库在一个上正常工作。另一方面,类方法返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23379630/

相关文章:

c - c 中 msgrcv 的参数无效

无法打开共享对象文件: No such file or directory | including libbpf with userspace program

c++ - const B 和 const A* 不兼容,即使 B 是 A* 的别名

c++ - 子类如何使用与子类相同的方法名调用父类(super class)的方法?

c - 在 OS X 上保留内存

c - 如何使用柠檬处理带有变量的表达式

c++ - 函数的模板返回类型编译错误

c++ - 从文件读取值时附加到输出的垃圾

python - 当负载均衡器就位时,如何检查 wget 命令请求是否由特定服务器提供服务?

c - 原子写入文件描述符