【问题标题】:Why I can not store the address of one variable in "Prolog+C"?为什么我不能在“Prolog+C”中存储一个变量的地址?
【发布时间】:2014-04-12 18:26:00
【问题描述】:

所以基本上我想从 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

我错了吗?谁能帮帮我?

【问题讨论】:

    标签: c prolog ffi gnu-prolog


    【解决方案1】:

    有区别。 在您的函数fun2 中,您会在堆栈上获得一个整数,&amp;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 位 intel 上,通常int 是 32 位整数,而指针是 64 位无符号整数,不适合 32 位。

    【讨论】:

      【解决方案2】:

      只是一个猜测,但它是传递给 prolog 的整数大小的限制吗?

      我不知道 gnu prolog,但在 swi prolog 中有一个特殊的调用 PL_get_pointer 和 PL_put_pointer 专门用于处理地址。PL_get_integer 和 PL_put_integer 不起作用。看看 gnu 中的等价物。地址可能被破坏了。

      编辑:您可能只需要将它从 int 更改为 long 或 double.. 类似的东西。

      【讨论】:

        猜你喜欢
        • 2021-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        相关资源
        最近更新 更多