在PHP7.4中加载带有FFI的库时出现问题
我在使用第三方时遇到了问题。所以PHP中的库与新的FFI一起使用。 当我运行这段代码时:在PHP7.4中加载带有FFI的库时出现问题,php,ffi,php-ffi,Php,Ffi,Php Ffi,我在使用第三方时遇到了问题。所以PHP中的库与新的FFI一起使用。 当我运行这段代码时: <?php $ffi = FFI::cdef('typedef int (*NFE_Nome)(const char* sNome, int* esTamanho);', 'libacbrnfe64.so'); 这是库本身、我的PHP配置还是其他方面的问题?这让我很困惑,因为我可以用这个C++代码正常使用这个库: #include <iostream> #include <dlf
<?php
$ffi = FFI::cdef('typedef int (*NFE_Nome)(const char* sNome, int* esTamanho);', 'libacbrnfe64.so');
这是库本身、我的PHP配置还是其他方面的问题?这让我很困惑,因为我可以用这个C++代码正常使用这个库:
#include <iostream>
#include <dlfcn.h>
typedef int (*NFE_Nome)(const char* sNome, int* esTamanho);
#define BUFFER_LEN 256
int main() {
void *lib = dlopen("libacbrnfe64.so", RTLD_LAZY);
auto libMethod = (NFE_Nome) dlsym(lib, "NFE_Nome");
const std::string bufferNome(BUFFER_LEN, ' ');
int bufferNomeLength = BUFFER_LEN;
libMethod(bufferNome.c_str(), &bufferNomeLength);
std::cout << bufferNome << std::endl;
return 0;
}
#包括
#包括
typedef int(*NFE_Nome)(常量字符*sNome,int*esTamanho);
#定义缓冲区长度256
int main(){
void*lib=dlopen(“libacbrnfe64.so”,RTLD_-LAZY);
自动libMethod=(NFE_Nome)dlsym(lib,“NFE_Nome”);
常量std::字符串bufferNome(BUFFER_LEN',);
int bufferNomeLength=缓冲区长度;
libMethod(bufferNome.c_str(),&bufferNomeLength);
标准::cout--编辑--
这个问题是两个不同程序中的两个错误造成的
链接共享对象时,fpc-3.0.0(或更新版本)会将其添加到依赖项中(作为第一个依赖项):/lib64/ld-linux-x86-64.so.2
ld-linux-x86-64.so.2导出一个calloc
变量,该变量不会(总是)清除它返回的内存(详细信息如下)
建议的解决方法是在一个单独的过程中链接(使用-E
(或-Cn
)选项fpc
),但在运行/ppas.sh
修复link.res
文件之前。为此,我破解了这个awk脚本,但我确实觉得它有点笨拙:
#!/usr/bin/awk -f
$0=="INPUT(" { state=1; next; }
$0=="/lib64/ld-linux-x86-64.so.2" { state=2; next; }
$0==")" && state>0 { state=0;next; }
state==1 { print "INPUT("; state=0; }
{ print $0; }
--原始答案--
听起来像是链接问题:您可能已将/lib64/ld-linux-x86-64.so.2
添加到依赖共享库中,这既不是必需的,也不是有用的
实际上,它产生了一个返回非零内存的calloc
版本。详细信息如下所述:这里:
建议的解决方案:根据示例更改悬挂机构:
- gcc -shared -o demodule.so demodule.o /lib64/ld-linux-x86-64.so.2 -lglib-2.0
+ gcc -shared -o demodule.so demodule.o -lglib-2.0
可以使用readelf-d
检查差异。错误:
Dynamic section at offset 0x828 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
0x0000000000000001 (NEEDED) Shared library: [libglib-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
右输出:
Dynamic section at offset 0x7f8 contains 25 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libglib-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
另外,使用命令ldd demodule.so
时,包含/lib64/ld-linux-x86-64.so.2
的行应该是最后一行
编辑:sourceware.org上关于此问题的讨论:
编辑:在Freepascal端:完全相同的错误。该库最初是用Pascal编写的,用Lazarus编译的。我在C编程或使用共享库方面没有太多经验,但这可能是问题的原因吗?您使用的是最新的
php
和libffi
版本(php-7.4.2和libffi-3.3)是的,我是,PHP7.4.2和LBFFII 3.3-2.3WHY,我编译了那些来自源的;在AIX/PowerPC和Linux /x64上尝试了PHP程序,但是不能重现这个问题。虽然我确实失败了加载错误,除非我把文件名改为“代码> ./LabBrBNFE64。所以,”,请注意,我永远不会用C++来实现插件。C++与动态负载不兼容。(或任何事情。)刚刚在另一台计算机上尝试过,现在我得到了以下错误:ld.so:dl minimal.c:126:realloc:Assertion`ptr==alloc_last_block'检测到不一致性失败!以下是我正在使用的库的二进制文件:因此,共享对象不是使用gcc编译的。它是一个Lazarus项目,因此使用fpc。我可以访问源代码code,但不知道如何告诉fpc不要使用ld-linux-x86-64library@HevertonConegliandeFreitas请引用链接命令(即使它是一个用户友好的IDE,也可能显示链接时执行的命令)。我成功地链接了库,但没有错误的依赖项。如果您将参数-Cn传递给fpc,它会忽略链接阶段。然后它会生成两个文件,一个名为ppas.sh,其中包含链接项目的说明,另一个名为link.res的文件,其中包含要链接的所有参数。在link.res文件的末尾,有一行如下所示:INPUT(/lib64/ld-linux-x86-64.so.2)。我刚刚删除了这一行并执行了.sh脚本,现在我可以将该库加载到PHP代码中,而无需修改errors@HevertonConegliandeFreitas我的测试用例没有显示这一点;猜测是因为我的fpc很旧(2.6.4),而我的测试库几乎是空的。问题是,我对免费的Pascal一无所知。也许你可以共享一些非常重要的示例源文件,这样我就可以重现这种行为。我对Pascal也一无所知;)我尝试使用的库是一组开源库,用于与巴西联邦税务局进行一些财政整合:
Dynamic section at offset 0x7f8 contains 25 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libglib-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]