So basically my test is on 32bit x86 Linux, I use GNU Prolog 1.4.4
Here is the case, I have function ptr.c
+ pro.pl
+ interface.c
In the ptr.c
, I use a wrapper to call a Prolog
function in the pro.pl
, then in the pro.pl
, I use a prolog c interface to call a C function in interface.c
, the argument is a C pointer.
I put some code here for each file:
ptr.c:
int C_wrapper_foo(int * e)
{
int return_value;
int func;
PlTerm arg[2]; // function variable + return value insert
PlBool res;
func = Pl_Find_Atom("foo"); // function name insert
Pl_Query_Begin(PL_FALSE);
printf("%p\n", e);
arg[0] = Pl_Mk_Integer((unsigned int)e); // See, here I put pointer e as an arg
arg[1] = Pl_Mk_Variable();
res = Pl_Query_Call(func, 2, arg); // insert (variable+return value)
return_value = Pl_Rd_Integer(arg[1]); // insert ()
Pl_Query_End(PL_KEEP_FOR_PROLOG);
return return_value;
}
See, I put pointer e
as the argument into Prolog.
Then in the Prolog code:
:- foreign(foo_c_instr(+integer)).
foo(E, FOO_RET) :-
foo_c_instr_0(E).
This is just a call into c function foo_c_instr
in interface.c
file.
PlBool foo_c_instr(int * e)
{
printf("%p\n", e);
return PL_TRUE;
}
The weird thing is that:
for example, the value of pointer e
in the original ptr.c
file is 0xbf9d4e4c, however, in the interface.c
file, its value becomes 0xff9d4e4c!!!
This is so weird and I have debugged it for quite a while, but I just don't know what is wrong...
The interface I use to pass the pointer argument is:
arg[0] = Pl_Mk_Integer((unsigned int)e);
I read the manual of gnu-prolog, and tried
arg[0] = Pl_Mk_Positive((unsigned int)e);
arg[0] = Pl_Mk_Integer((int)e);
arg[0] = Pl_Mk_Positive((int)e);
but it just can't work....
Could anyone give some help?
OK, so here is my ad-hoc solution:
In the interface.c
function, I do this mask on the pointer:
PlBool foo_c_instr(int * e)
{
e = (unsigned int)e&0xbfffffff;
printf("%p\n", e);
return PL_TRUE;
}
then it works fine...