Introduction
This is an overview of an interface which allows SWI-Prolog programs to dynamically create and manipulate .NET objects.
Here are some significant features of the interface and its implementation:
?- use_module(library(swicli)). ?- cli_call('System.Threading.ThreadPool','GetAvailableThreads'(X,Y),_). X=499, Y=1000
?- cli_call('System.Environment','Version',X),cli_writeln(X). "2.0.50727.5448" X = @'C#499252128'.
== Doc root will be findable from http://code.google.com/p/opensim4opencog/wiki/SwiCLI
@see CSharp.txt
cli_load_lib/4 is what was used to bootstrap SWICLI (it defined the next stage where cli_load_assembly/1) became present
remember to: export LD_LIBRARY_PATH=/development/opensim4opencog/bin:$LD_LIBRARY_PATH
in swicli.pl we called:
:- cli_load_lib('SWIProlog','Swicli.Library','Swicli.Library.Embedded','install').
?- cli_load_assembly('Swicli.Library').
The uncaught version allows exception to come from .NET
?- cli_load_assembly_methods('Swicli.Library', @false, "cli_").
?- cli_add_assembly_search_path('c:/myproj/bin'). ?- cli_remove_assembly_search_path('c:/myproj/bin').
This now makes the System assembly resolver see Assemblies in that directory
Simular to Windows: adding to %PATH% Linux: adding to $MONO_PATH
15 ?- cli_to_ref(sbyte(127),O),cli_get_type(O,T),cli_writeln(O is T). "127"is"System.SByte" O = @'C#283319280', T = @'C#283324332'. 16 ?- cli_to_ref(long(127),O),cli_get_type(O,T),cli_writeln(O is T). "127"is"System.Int64" O = @'C#283345876', T = @'C#283345868'. 17 ?- cli_to_ref(ulong(127),O),cli_get_type(O,T),cli_writeln(O is T). "127"is"System.UInt64" O = @'C#283346772', T = @'C#283346760'. 15 ?- cli_to_ref(sbyte(127),O),cli_get_type(O,T),cli_writeln(O is T). "127"is"System.SByte" O = @'C#283319280', T = @'C#283324332'. 16 ?- cli_to_ref(long(127),O),cli_get_type(O,T),cli_writeln(O is T). "127"is"System.Int64" O = @'C#283345876', T = @'C#283345868'. 18 ?- cli_to_ref(343434127,O),cli_get_type(O,T),cli_writeln(O is T). "343434127"is"System.Int32" O = @'C#281925284', T = @'C#281925280'. 19 ?- cli_to_ref(3434341271,O),cli_get_type(O,T),cli_writeln(O is T). "3434341271"is"System.UInt64" O = @'C#281926616', T = @'C#283346760'. 21 ?- cli_to_ref(343434127111,O),cli_get_type(O,T),cli_writeln(O is T). "343434127111"is"System.UInt64" O = @'C#281930092', T = @'C#283346760'. 28 ?- cli_to_ref(34343412711111111111111111111111111111,O),cli_get_type(O,T),cli_writeln(O is T). "34343412711111111111111111111111111111"is"java.math.BigInteger" O = @'C#281813796', T = @'C#281810860'.
?- cli_cast(1,'double',X). X = @'C#568261440'. ?- cli_cast(1,'System.DayOfWeek',X). X = @'C#568269000'. ?- cli_cast_immediate(1,'System.DayOfWeek',X). X = enum('DayOfWeek', 'Monday'). ?- cli_cast_immediate(1.0,'System.DayOfWeek',X). X = enum('DayOfWeek', 'Monday'). ?- cli_cast_immediate(1.01,'System.DayOfWeek',X). ERROR: Having time of it convcerting 1.01 to System.DayOfWeek why System.ArgumentException: Requested value '1.01' was not found.
?- cli_new('System.Collections.Generic.List'('System.String'),[int],[10],Obj). Obj = @'C#516939544'. ?- cli_get($Obj,'Count',Out). Out = 0. ?- cli_call($Obj,'Add'("foo"),Out). Out = @void. ?- cli_call($Obj,'Add'("bar"),Out). Out = @void. ?- cli_get($Out,'Count',Out). Out = 2. ?- cli_col($Obj,E). E = "foo" ; E = "bar" ; false.
?- member_elipse(E,{a,b,c}). E = a ; E = b ; E = c.
?- cli_cast("Yellow",'System.Drawing.Color',C),cli_to_data(C,D),writeq(D). ["R"=255,"G"=255,"B"=0,"A"=255,"IsKnownColor"= @true,"IsEmpty"= @false,"IsNamedColor"= @true,"IsSystemColor"= @false,"Name"="Yellow"] C = @'C#802963000', D = ["R"=255, "G"=255, "B"=0, "A"=255, "IsKnownColor"= @true, "IsEmpty"= @false, "IsNamedColor"= @true, "IsSystemColor"= @ ..., ... = ...].
?- cli_load_assembly('IKVM.OpenJDK.Core') ?- cli_new('java.lang.Long'(long),[44],Out),cli_to_str(Out,Str).
same as..
?- cli_new('java.lang.Long',[long],[44],Out),cli_to_str(Out,Str).
arity 4 exists to specify generic types
?- cli_new('System.Int64',[int],[44],Out),cli_to_str(Out,Str). ?- cli_new('System.Text.StringBuilder',[string],["hi there"],Out),cli_to_str(Out,Str). ?- cli_new('System.Int32'(int),[44],Out),cli_to_str(Out,Str).
ClazzSpec can be:
if ClazzSpec is an object (non-array) type or descriptor and Params is a list of values or references, then Result is the result of an invocation of that type's most specifically-typed constructor to whose respective formal parameters the actual Params are assignable (and assigned)
if ClazzSpec is an array type or descriptor and Params is a list of values or references, each of which is (independently) assignable to the array element type, then Result is a new array of as many elements as Params has members, initialised with the respective members of Params;
if ClazzSpec is an array type or descriptor and Params is a non-negative integer N, then Result is a new array of that type, with N elements, each initialised to CLR's appropriate default value for the type;
If Result is {Term} then we attempt to convert a new PlTerm instance to a corresponding term; this is of little obvious use here, but is consistent with cli_call/4 and cli_get/3
Make a "new string[32]" and get it's length.
?- cli_new(array(string),[int],[32],O),cli_get(O,'Length',L).
MethodSpec should be:
Params should be:
CallTerm should be:
finally, an attempt will be made to unify Result with the returned result
finally, an attempt will be made to unify Result with the returned result
MemberSpec can be:
IndexValues can be:
Value: