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 and Download 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
cli_memb(O,X):-cli_members(O,Y),member(X,Y). cli_memb(O,F,X):-cli_memb(O,X),member(F,[f,p, c,m ,e]),functor(X,F,_).
Object to the member infos of it
3 ?- cli_new('System.Collections.Generic.List'(string),[int],[10],O),cli_members(O,M),!,member(E,M),writeq(E),nl,fail. f(0,'_items'(arrayOf('String'))) f(1,'_size'('Int32')) f(2,'_version'('Int32')) f(3,'_syncRoot'('Object')) f(4,'_emptyArray'(arrayOf('String'))) f(5,'_defaultCapacity'('Int32')) p(0,'Capacity'('Int32')) p(1,'Count'('Int32')) p(2,'System.Collections.IList.IsFixedSize'('Boolean')) p(3,'System.Collections.Generic.ICollection<T>.IsReadOnly'('Boolean')) p(4,'System.Collections.IList.IsReadOnly'('Boolean')) p(5,'System.Collections.ICollection.IsSynchronized'('Boolean')) p(6,'System.Collections.ICollection.SyncRoot'('Object')) p(7,'Item'('String')) p(8,'System.Collections.IList.Item'('Object')) m(0,'ConvertAll'('Converter'('String',<))) m(1,get_Capacity) m(2,set_Capacity('Int32')) m(3,get_Count) m(4,'System.Collections.IList.get_is_FixedSize') m(5,'System.Collections.Generic.ICollection<T>.get_is_ReadOnly') m(6,'System.Collections.IList.get_is_ReadOnly') m(7,'System.Collections.ICollection.get_is_Synchronized') m(8,'System.Collections.ICollection.get_SyncRoot') m(9,get_item('Int32')) m(10,set_item('Int32','String')) m(11,'IsCompatibleObject'('Object')) m(12,'VerifyValueType'('Object')) m(13,'System.Collections.IList.get_item'('Int32')) m(14,'System.Collections.IList.set_item'('Int32','Object')) m(15,'Add'('String')) m(16,'System.Collections.IList.Add'('Object')) m(17,'AddRange'('System.Collections.Generic.IEnumerable'('String'))) m(18,'AsReadOnly') m(19,'BinarySearch'('Int32','Int32','String','System.Collections.Generic.IComparer'('String'))) m(20,'BinarySearch'('String')) m(21,'BinarySearch'('String','System.Collections.Generic.IComparer'('String'))) m(22,'Clear') m(23,'Contains'('String')) m(24,'System.Collections.IList.Contains'('Object')) m(25,'CopyTo'(arrayOf('String'))) m(26,'System.Collections.ICollection.CopyTo'('Array','Int32')) m(27,'CopyTo'('Int32',arrayOf('String'),'Int32','Int32')) m(28,'CopyTo'(arrayOf('String'),'Int32')) m(29,'EnsureCapacity'('Int32')) m(30,'Exists'('System.Predicate'('String'))) m(31,'Find'('System.Predicate'('String'))) m(32,'FindAll'('System.Predicate'('String'))) m(33,'FindIndex'('System.Predicate'('String'))) m(34,'FindIndex'('Int32','System.Predicate'('String'))) m(35,'FindIndex'('Int32','Int32','System.Predicate'('String'))) m(36,'FindLast'('System.Predicate'('String'))) m(37,'FindLastIndex'('System.Predicate'('String'))) m(38,'FindLastIndex'('Int32','System.Predicate'('String'))) m(39,'FindLastIndex'('Int32','Int32','System.Predicate'('String'))) m(40,'ForEach'('System.Action'('String'))) m(41,'GetEnumerator') m(42,'System.Collections.Generic.IEnumerable<T>.GetEnumerator') m(43,'System.Collections.IEnumerable.GetEnumerator') m(44,'GetRange'('Int32','Int32')) m(45,'IndexOf'('String')) m(46,'System.Collections.IList.IndexOf'('Object')) m(47,'IndexOf'('String','Int32')) m(48,'IndexOf'('String','Int32','Int32')) m(49,'Insert'('Int32','String')) m(50,'System.Collections.IList.Insert'('Int32','Object')) m(51,'InsertRange'('Int32','System.Collections.Generic.IEnumerable'('String'))) m(52,'LastIndexOf'('String')) m(53,'LastIndexOf'('String','Int32')) m(54,'LastIndexOf'('String','Int32','Int32')) m(55,'Remove'('String')) m(56,'System.Collections.IList.Remove'('Object')) m(57,'RemoveAll'('System.Predicate'('String'))) m(58,'RemoveAt'('Int32')) m(59,'RemoveRange'('Int32','Int32')) m(60,'Reverse') m(61,'Reverse'('Int32','Int32')) m(62,'Sort') m(63,'Sort'('System.Collections.Generic.IComparer'('String'))) m(64,'Sort'('Int32','Int32','System.Collections.Generic.IComparer'('String'))) m(65,'Sort'('System.Comparison'('String'))) m(66,'ToArray') m(67,'TrimExcess') m(68,'TrueForAll'('System.Predicate'('String'))) m(69,'ToString') m(70,'Equals'('Object')) m(71,'GetHashCode') m(72,'GetType') m(73,'Finalize') m(74,'MemberwiseClone') c(0,'List`1') c(1,'List`1'('Int32')) c(2,'List`1'('System.Collections.Generic.IEnumerable'('String'))) c(3,'List`1')
?- cli_new(array(string),[int],[32],O),cli_add_tag(O,'string32'). ?- cli_get_type(@(string32),T),cli_writeln(T).
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
_raw is the foreing impls of the first two (Actually the above search impl is done from this _raw) _field will only try to set fields _property will only try to set fields
ClazzOrInstance can be:
MemberSpec can be:
IndexValues can be:
Value: