DelegateParameterVarArgs Delegate

SbsSW.SwiPlCs

Copy image CopyHover image
Swi-cs-pl - A CSharp class library to connect .NET languages with SWI-Prolog DelegateParameterVarArgs Delegate
SwiPlCs interfaceSbsSW.SwiPlCs.CallbackDelegateParameterVarArgs

With this delegate you can build a call-back predicate with a variable amount of parameters.

Declaration Syntax
C# Visual Basic Visual C++ F#
public delegate bool DelegateParameterVarArgs(
	PlTermV termVector
)
Public Delegate Function DelegateParameterVarArgs ( 
	termVector As PlTermV
) As Boolean
public delegate bool DelegateParameterVarArgs(
	PlTermV termVector
)
type DelegateParameterVarArgs = 
    delegate of 
        termVector : PlTermV -> bool
Parameters
termVector (PlTermV)
The termVector representing the arguments which can be accessed by the indexer of PlTermV see PlTermV. The amount of parameters is in Size
Return Value
Boolean
True for succeeding otherwise false for fail
Remarks

TODO: This do *NOT* work on 64-Bit systems. Hope to Fix this in the future.

It seems to be impossible to marshal two parameter which are bigger than 8 byte into one struct. Perhaps there is a way in CLI :-(

The problem are the parameters of the call back method. These are in C foreign_t (f)(term_t t0, int a, control_t ctx)) (see SWI-cpp.h) If we provide DelegateParameterVarArgs(PlTerm term, int arity); and do in the callback Method something like
 Copy imageCopy
public static bool my_call_back(PlTerm term, int arity)
{
     PlTermV args = new PlTermV(term, arity);   // This constructor do *not* exist
}
every thing work fine. The drawback is this ugly ctor. It might be better to do PlTermV args = PlTermV.VarArgs(term, arity); with a strong recommendation to use it *OINLY* in this call back scenario.
Examples
  Copy imageCopy
public void t_varargs()
{
    Delegate d = new DelegateParameterVarArgs(my_concat_atom);
    PlEngine.RegisterForeign("my_concat_atom", 4, d);
    PlEngine.RegisterForeign("my_concat_atom", 7, d);
    for (int i = 1; i < 10; i++)
    {
        PlTerm t = PlQuery.PlCallQuery("my_concat_atom(a,b,c, X)");
        Assert.AreEqual("abc", t.ToString(), "my_concat_atom failed!");
        t = PlQuery.PlCallQuery("my_concat_atom(a,b,c,d,e,f, X)");
        Assert.AreEqual("abcdef", t.ToString(), "my_concat_atom failed!");
    }
}
public static bool my_concat_atom(PlTermV term1)
{
    System.Diagnostics.Debug.Print("my_concat_atom called with term - {0}", term1.ToString());

    int arity = term1.Size;
    string sRet = "";
    PlTerm termOut = term1[arity -1];

    for (int i = 0; i < arity-1; i++)
    {
        sRet += term1[i].ToString();
    }
    termOut.Unify(sRet);
    return true;
}

Assembly: SwiPlCs (Module: SwiPlCs.dll) Version: 1.1.60605.0 (1.1.60605.0)