首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回双(libffi)函数的值错误

返回双(libffi)函数的值错误
EN

Stack Overflow用户
提问于 2020-05-03 16:01:52
回答 2查看 252关注 0票数 0

似乎当函数返回其值时,返回双数据类型的函数(从libffi返回)不正确,下面是我使用的代码:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <ffi.h>
#include <math.h>  // The make call the function `cos` by the FFI.

int main()
{
  ffi_cif cif;
  ffi_type *args[1];
  void *values[1];
  ffi_arg rc;

  args[0] = &ffi_type_double;

  void *ptr = malloc(sizeof(double));
  *((double *)ptr) = 3.0;
  values[0] = ptr;

  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_double, args) == FFI_OK)
      ffi_call(&cif, cos, &rc, values);

  printf("%f\n", (double)rc);

  return 0;
}

结果如下:13830464316077631000.000000

ffi_arg类型是unsigned long long的别名。文档指出,传递给ffi_arg函数的ffi_arg类型的参数用于存储比sizeof(ffi_arg)小的数据,否则它就是内存中数据的指针:

对于非浮点数类型,rvalue必须指向sizeof(ffi_arg)或更大的存储。对于较小的返回值类型,必须使用ffi_argffi_sarg整数类型来保存返回值。

(call.3.en.html)

因此,我尝试了一个指针取消引用:

代码语言:javascript
复制
void* rc;
// The code to call the function and initialize the CIF...
double my_value = *(double *)((void *)rc);

程序崩溃了。

如何访问使用rc变量存储的值?

编辑1

用于编译程序的命令行:

代码语言:javascript
复制
gcc source.c -lffi -o source

编译时没有错误或警告。

编辑2

在添加了‘-Wall’构建选项之后,我得到:

代码语言:javascript
复制
warning: passing argument 2 of 'ffi_call' from incompatible pointer type [-Wincompatible-pointer-types]
ffi_call(&cif, cos, &rc, values);
               ^~~

这个警告在libffi示例中似乎被忽略了。给出的示例对我非常有用(有此警告)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-03 17:23:59

问题很简单。ffi_arg不是您应该将返回值放入的类型。相反,第三个参数被定义为一个指向空的指针,该指针应该指向一个适当大的对象,该对象包含返回值和适当的对齐方式,并且具有正确的类型,或者解释为适当的对象:

代码语言:javascript
复制
double rv;
...
ffi_call(&cif, cos, &rv, values);

代码语言:javascript
复制
void *rv = malloc(sizeof (double));
...
ffi_call(&cif, cos, rv, values);
double value = *(double *)rv;

至于警告,这是因为libffi代码不是严格可移植的。函数指针不能自动转换为void *。可以使用显式强制转换来沉默警告:

代码语言:javascript
复制
ffi_call(&cif, (void *)cos, rv, values);

至少它并没有使它比现在更错误。

票数 3
EN

Stack Overflow用户

发布于 2020-05-03 16:48:15

编辑-根据文档

对于非浮点类型,ffi_arg必须指向大小(Ffi_arg)或更大的存储。对于较小的返回值类型,必须使用ffi_arg或ffi_sarg整数类型来保存返回值。

ffi_call的函数定义是

代码语言:javascript
复制
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);

您不需要将一个ffi_arg传递给函数,而是传递一个void*,它分配了一个double空间。

代码语言:javascript
复制
void* rc = malloc(sizeof(double));
ffi_call(&cif, cos, rc, values);
printf("%f\n", *(double *)rc);

这将导致一个正确的答案,而不必对被调用的函数作出任何假设。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61577543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档