函数总是 returns 无意义的值

Function always returns meaningless value

我正在编写要由 cffi 在 pypy3 中调用的 C 函数。但是,包装函数总是 return pypy3 中的无意义值,无论真正的 return 值是多少。

printf() 函数的输出告诉我在 C 函数中一切正常,但是 pypy3 中的 return 值发生了变化。

C函数是这样写的:

double test(){
    return 5.12;
}

double test2(){
    double tmp=test();
    printf("!!!!!!!%f\n",tmp);
    return tmp;
}

cffi构建脚本如下:

from cffi import FFI
ffibuilder = FFI()

ffibuilder.set_source("_faststr_cffi",
                      """
                        #include <Python.h>
                        #include "stdint.h"
                        #include <string.h>
                        typedef uint32_t char32_t;
                      """,
                      sources=['faststr_purec.c']
                      )   # library name, for the linker

ffibuilder.cdef("""
double test();
double test2();
""")

if __name__ == "__main__":
    ffibuilder.compile(verbose=True)

我尝试在 pypy3 控制台中调用 test2():

>>>> from _faststr_cffi import lib
>>>> lib.test2()
!!!!!!!5.120000
16.0

printf 告诉我 return 值应该是 5.120000,但在 pypy3 中 returned 16.0。

我发现了一些线索:如果我更改 test2() printf 函数中的字符串,则 pypy3 中 test2 的 return 值也会更改。

更新:cpython 3.6.7 中的结果相同,因此不是 pypy3 问题

问题如下:

在这里,您声明函数 test()test2():

ffibuilder.cdef("""
double test();
double test2();
""")

这些声明仅供 cffi 接口知道要使用的 return 值。但是缺少本机 c 函数 test()test2() 的声明。因此,它们被隐式声明为 returning int!

现在当从 test2

调用函数 test() 时(隐式声明为 returning int)
double tmp = test();

return tmp;

编译后的代码读取了错误的寄存器(因为它寻找的是一个整数值)并将其转换为双精度值,return结果是它。碰巧的是,最后一个整数结果是 printf() 的结果,这是打印字符串的长度。因此,在您的情况下,您会得到 16 的结果。

修复方法是,正确声明函数 test()test2()

ffibuilder.set_source("_faststr_cffi",
                  """
                    #include <Python.h>
                    #include "stdint.h"
                    #include <string.h>
                    typedef uint32_t char32_t;
                    double test();
                    double test2();
                  """,
                  sources=['faststr_purec.c']
                  )   # library name, for the linker

然后它应该按预期工作。