2

したがって、基本的に私のテストは 32 ビット x86 Linux で行われます。GNU Prolog 1.4.4

これがケースです、私は関数を持っていますptr.c+ pro.pl+interface.c

ではptr.c、ラッパーを使用して 内のProlog関数を呼び出しますpro.pl。次に、 ではpro.pl、prolog c インターフェイスを使用して 内の C 関数を呼び出します。interface.c引数はC ポインタです。

ファイルごとにいくつかのコードをここに配置します。

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;

  }

ほら、ポインタeを引数としてPrologに入れました。

次に、プロローグ コードで:

:- foreign(foo_c_instr(+integer)).

foo(E, FOO_RET) :-

foo_c_instr_0(E).

foo_c_instrこれは、interface.cファイル内の c 関数への単なる呼び出しです。

PlBool foo_c_instr(int * e)
{
    printf("%p\n", e);
   return PL_TRUE;
}

奇妙なことは次のとおりです。

たとえば、e元のptr.cファイルのポインターの値は0xbf9d4e4cですが、interface.cファイルでは、その値は0xff9d4e4cになります!!!

これはとても奇妙で、かなり長い間デバッグしてきましたが、何が悪いのかわかりません...

ポインター引数を渡すために使用するインターフェイスは次のとおりです。

arg[0] = Pl_Mk_Integer((unsigned int)e); 

gnu-prologのマニュアルを読んで、試してみました

arg[0] = Pl_Mk_Positive((unsigned int)e);
arg[0] = Pl_Mk_Integer((int)e);
arg[0] = Pl_Mk_Positive((int)e);

しかし、それはうまくいきません....

誰か助けてくれませんか?

4

1 に答える 1

0

OK、これが私のアドホックな解決策です:

関数ではinterface.c、ポインターに対して次のマスクを行います。

PlBool foo_c_instr(int * e)
{
   e = (unsigned int)e&0xbfffffff;
   printf("%p\n", e);
   return PL_TRUE;
}

その後、正常に動作します...

于 2014-06-10T17:58:23.400 に答える