函数总是返回无意义的值
Posted
技术标签:
【中文标题】函数总是返回无意义的值【英文标题】:Function always returns meaningless value 【发布时间】:2019-12-03 17:16:03 【问题描述】:我正在编写由 cffi 在 pypy3 中调用的 C 函数。但是,无论真正的返回值是什么,包装函数在 pypy3 中总是返回一个无意义的值。
printf()
函数的输出告诉我在 C 函数中一切正常,但是 pypy3 中的返回值发生了变化。
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 告诉我返回值应该是 5.120000,但它在 pypy3 中返回了 16.0。
我发现了一些线索:如果我在test2() printf函数中改变字符串,pypy3中test2的返回值就会改变。
更新:cpython 3.6.7 中的结果是一样的,所以这不是 pypy3 问题
【问题讨论】:
奇怪的问题,但总是写的字符数吗?因为这就是这里的样子 @EdwardMinnix 确实,这是一个很好的捕获,这导致了错误行为的原因的识别 【参考方案1】:问题如下:
在这里,您声明函数test()
和test2()
:
ffibuilder.cdef("""
double test();
double test2();
""")
这些声明只是为了让 cffi 接口知道要使用的返回值。但是缺少原生 c 函数 test()
和 test2()
的声明。因此,它们被隐式声明返回 int
!
现在当函数 test()
从 test2 被调用(隐式声明返回 int)时
double tmp = test();
return tmp;
编译后的代码读取了错误的寄存器(因为它查找的是整数值)并将其转换为双精度值,并将其作为结果返回。碰巧的是,最后一个整数结果是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
然后它应该按预期工作。
【讨论】:
我认为你是对的。但是你能解释一下为什么 printf 打印正确的返回值 5.120000 吗? @Jay 这是调用约定的问题。test()
在寄存器 A 中返回一个 double,但 test2()
在寄存器 B 中查找一个整数,因为 test()
被(隐式)声明返回一个整数。寄存器B中存储的整数是printf()
的返回值,在从test()
返回之前不会被覆盖。以上是关于函数总是返回无意义的值的主要内容,如果未能解决你的问题,请参考以下文章