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



所以基本上我想从Prolog中调用一些C代码,下面是代码:

Prolog:

:-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("%dn", *res);
    if(res==NULL){
      return PL_FALSE;
    }else{
      return PL_TRUE;
    }
}
PlBool fun2(int val, int* res){
   *res = &val;
   printf("%pn", *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的大小可以不同。使用int来存储pointer是行不通的,例如在64位整数上,通常int是32位整数,指针是64位无符号整数,不适合32位。

只是猜测,但这是传递到prolog中的整数大小的限制吗?

我不知道gnu-prolog,但在swi-prolog中有一个专门用于处理地址的特殊调用PL_get_pointer和PL_put_pointer。。PL_get_integer和PL_put_integer将不起作用。在gnu中查找等效项。。地址可能被篡改了。

编辑:您可能只需要将其从int更改为long或double。。诸如此类的事情。

相关内容

  • 没有找到相关文章

最新更新