简体   繁体   English

功能总是返回毫无意义的价值

[英]Function always returns meaningless value

I'm writing C functions to be called in pypy3 by cffi. 我正在编写c函数,由cffi在pypy3中调用。 However, the wrapped functions always return a meaningless value in pypy3, no matter what the true return value is. 但是,无论真正的返回值是什么,包装函数总是在pypy3中返回无意义的值。

The output of the printf() function tells me everything works fine in the C function, but the return value in pypy3 is changed. printf()函数的输出告诉我C函数中的一切正常,但pypy3中的返回值已更改。

The C function is written like this: C函数是这样写的:

double test(){
    return 5.12;
}

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

The cffi build script is as follows: 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)

I tried to call test2() in pypy3 console: 我试着在pypy3控制台中调用test2():

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

The printf tells me that return value should be 5.120000, but it returned 16.0 in pypy3. printf告诉我返回值应该是5.120000,但它在pypy3中返回16.0。

I found some clue: If I change the string in test2() printf function, the return value of test2 in pypy3 is changed. 我找到了一些线索:如果我在test2()printf函数中更改了字符串,则更改pypy3中test2的返回值。

Update: Result in cpython 3.6.7 is the same so it's not a pypy3 problem 更新:cpython 3.6.7中的结果是相同的,因此它不是pypy3问题

The problem is as follows: 问题如下:

Here, you declare the functions test() and test2() : 在这里,您声明函数test()test2()

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

These declarations are only for the cffi interface to know the return values to use. 这些声明仅适用于cffi接口,以了解要使用的返回值。 But the declarations for the native c functions test() and test2() are missing. 但缺少原生c函数test()test2()的声明。 Thus, they are implicitly declared returning int ! 因此,它们被隐式声明返回int

Now when the function test() is called (which is implicitly declared returning int) from test2 现在从test2调用函数test() (隐式声明返回int)

double tmp = test();

return tmp;

the compiled code reads the wrong register (because it looks for an integer value) and converts it to a double, returning it as a result. 已编译的代码读取错误的寄存器 (因为它查找整数值)并将其转换为double,因此返回它。 As it happens, the last integer result was the result of the printf() , which is the length of the printed string. 碰巧,最后一个整数结果是printf()的结果,它是打印字符串的长度。 Because of this, you get the result of 16 in your case. 因此,在您的情况下,您将获得16的结果。

The fix is, to declare the functions test() and test2() properly: 修复是,正确声明函数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

Then it should work as expected. 然后它应该按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM