c - 为什么我不能将一个变量的地址存储在 "Prolog+C"中?

标签 c prolog ffi gnu-prolog

基本上我想从 Prolog 调用一些 C 代码,代码如下:

序言:

:-foreign(fun1(+integer,-integer)).
:-foreign(fun2(+integer,-integer)). 

% p = b;
testfuna(Var, Val) :- fun1(Val, Var).
% p = &b;
testfunb(Var, Val) :- fun2(Val, Var).

main :-
A is 1,
testfuna(A, P),
write(P),
testfunb(A, P),
write(P),

% print out

write(A), nl.

C:

#include <gprolog.h>
#include <string.h>

PlBool fun1(int ptr, int* res){
    *res = ptr;
    printf("%d\n", *res);
    if(res==NULL){
      return PL_FALSE;
    }else{
      return PL_TRUE;
    }
}

PlBool fun2(int val, int* res){
   *res = &val;
   printf("%p\n", *res);
   if(res==NULL){
      return PL_FALSE;
   }else{
      return PL_TRUE;
   }
}

我用它来编译成二进制格式:

gplc -o sample sample.c sample.pl

问题是,在我运行这段代码后,输出是:

  1    <--- right
  1    <--- match, right!
  0xbff2160c       <-- it is on the stack
  -911860     <--- why?              

不明白为什么第四个输出是新的内存地址,按我的理解应该也是0xbff2160c

我错了吗?谁能给我一些帮助?

最佳答案

有区别。 在您的函数 fun2 中,您在堆栈上获得了一个整数,&val 是该整数的地址。

PlBool fun1(int ptr, int* res){
 *res = ptr;  /* ptr is what you got from prolog */
 ...
}

PlBool fun2(int val, int* res){
 *res = &val; /* val is a copy on the stack here, */
 /* you don't use at all what you got from prolog, only the address */
 /* of a local copy in the stack  */
 ...
}

此外,(我不知道任何序言,所以我不确定你在那部分做了什么)如果你试图将指针作为 int 传递,它不会工作。 通常,指针的大小和整数的大小可以不同。使用 int 存储 pointer 是行不通的,例如在 64 位英特尔上,通常 int 是 32 位整数,而指针是 64 位无符号整数,不适合 32 位。

关于c - 为什么我不能将一个变量的地址存储在 "Prolog+C"中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23034380/

相关文章:

c - C中的数组数据类型

database - Prolog 数据库查询

c - 从标准输入读取字符串长度

c - 阅读为 R 包编写的 C 代码。在哪里可以找到 RANDIN、UNIF、EPS 等的定义?

prolog - "Squares"Prolog中的逻辑谜语解决方案

prolog - 在河内序言塔上实现计数器

python - 与 Python 相比,在 Haskell 中调用 c 函数

c++ - 使用 ffi 将 C++ 数据类型导入 haskell

c - 为什么Ruby FFI在有头文件的情况下还需要调用attach_function?

c++ - 如何在 C 代码中模拟 C++ namespace 功能?