NAME
Win32::CLR - Use .NET Framework facilities in Perl
SYNOPSIS
use Win32::CLR;
use utf8;
# binmode STDOUT, ":encoding(Shift_JIS)"; # japanese character set
# creating instance
my $dt1 = Win32::CLR->create_instance("System.DateTime", 2007, 8, 9, 10, 11, 12);
# getting property
print $dt1->get_property("Year"), "\n"; # 2007
# calling method
my $dt2 = $dt1->call_method("AddYears", 3);
print $dt2->get_property("Year"), "\n"; # 2010
my $asm = "System.Windows.Forms, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089";
# loading assembly by name
Win32::CLR->load($asm);
# after loading assembly, System.Windows.Forms.* classes can be used
Win32::CLR->call_method(
"System.Windows.Forms.MessageBox", # type
"Show", # method
"Message", # parameter
"Title" # parameter
);
# creating generic instance
my $generic = "System.Collections.Generic.Dictionary<System.String, System.Int32>";
my $dict = Win32::CLR->create_instance($generic);
$dict->set_property("Item", "ABC", 4321); # dict["ABC"] = 4321;
print $dict->get_property("Item", "ABC"), "\n"; # 4321
DESCRIPTION
Win32::CLR provides utility methods to using Microsoft .NET Framework, also known as Common Language Runtime. It is available for creating object, calling method, accessing field or property, converting perl subroutine to delegate, loading assembly.
CLASS METHODS
- Win32::CLR->create_instance("TYPE", @PARAMS)
-
Creates .NET Framework object of TYPE. The constructor that matches @PARAMS is used.
my $dt = Win32::CLR->create_instance( "System.DateTime", 2007, 8, 9, 10, 11, 12 );
- Win32::CLR->call_method("TYPE", "NAME", @PARAMS)
-
Calls the static method declared in TYPE. @PARAMS must be primitive value or Win32::CLR instance. If @PARAMS contain array reference, it is converted to System.Array.
# in .net # static void MyType::Foo(String^ param); # in perl Win32::CLR->call_method("MyType", "Foo", "foo"); # static void MyType::Foo2(String^ param1, Int32 param2); Win32::CLR->call_method("MyType", "Foo2", "foo", 4321); # static void MyType::Foo3(array<Object^>^ params); Win32::CLR->call_method("MyType", "Foo3", ["foo", "bar", ...]);
- Win32::CLR->get_field("TYPE", "NAME", [$INDEX])
-
Returns the static field declared in TYPE. If field has index, optional parameter $INDEX can be used.
# in .net # field = MyType::Foo; Win32::CLR->get_field("MyType", "Foo"); # MyType::Foo[0] Win32::CLR->get_field("MyType", "Foo", 0);
- Win32::CLR->set_field("TYPE", "NAME", [$INDEX, ] $PARAM)
-
Sets $PARAM in the static field declared in TYPE. $PARAM must be primitive value or Win32::CLR instance. If field has index, optional parameter $INDEX can be used.
- Win32::CLR->get_property("TYPE", "NAME", [$INDEX])
-
Same as get_field, returns the static property declared in TYPE. Optionally, $INDEX can be used.
# in .net # dict["ABC"] $dict->get_property("Item", "ABC");
- Win32::CLR->set_property("TYPE", "NAME", [$INDEX, ] $PARAM)
-
Same as set_field, sets $PARAM in the static property declared in TYPE. Optionally, $INDEX can be used.
# in .net # dict["ABC"] = 4321; $dict->set_property("Item", "ABC", 4321);
- Win32::CLR->get_value("TYPE", "NAME", [$INDEX])
-
If property exists in TYPE, calls get_property, or otherwise calls get_field.
- Win32::CLR->set_value("TYPE", "NAME", [$INDEX, ] $PARAM)
-
Same as get_value, sets $PARAM in static property or field.
- Win32::CLR->add_event("TYPE", "NAME", $DELEG)
-
Sets event handler in the static event declared in TYPE. $DELEG must be System.Delegate or subroutine reference.
my $deleg = Win32::CLR->create_delegate( "System.EventHandler", sub {print "do something"}, ); $button->add_event("Click", $deleg); $button->remove_event("Click", $deleg); # directly, but addition only! $button->add_event("Click", sub {print "do something"});
- Win32::CLR->remove_event("TYPE", "NAME", $DELEG)
-
Removes event handler $DELEG from TYPE. $DELEG must be System.Delegate.
- Win32::CLR->create_delegate("TYPE", $CODE)
-
Creates System.Delegate from perl subroutine. $CODE can contain "sub_name" or \&sub_ref. TYPE is delegate type (ex. System.EventHandler).
my $deleg = Win32::CLR->create_delegate( "System.EventHandler", sub { my ($obj, $event_args) = @_; # do something ... } );
- Win32::CLR->create_array("TYPE", @PARAMS)
-
Creates TYPE of System.Array. @PARAMS is setted.
my $array = Win32::CLR->create_array("System.String", "A", "B", "C"); $array->call_method("GetValue", 0); # A $array->call_method("GetValue", 1); # B $array->call_method("GetValue", 2); # C
- Win32::CLR->create_enum("TYPE", "VALUE1, VALUE2, ...")
-
Creates System.Enum value. TYPE is enum type, VALUES contain list of named constants delimited by commas.
my $binding_flags = Win32::CLR->create_enum( "System.Reflection.BindingFlags", "InvokeMethod, NonPublic" );
- Win32::CLR->load("NAME")
-
Loads assembly by AssemblyQualifiedName. If assembly loaded once, it comes to be able to use the type in assembly. Loaded assembly is cached in memory, so reloading assembly is not required. NAME must be long form of the assembly name. It returns loaded System.Reflection.Assembly object.
my $name = "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; # $asm can be ignored my $asm = Win32::CLR->load($name); my $button = Win32::CLR->create_instance("System.Windows.Forms.Button");
- Win32::CLR->load_from("PATH")
-
Loads assembly from file. PATH is path to assembly file. It returns loaded System.Reflection.Assembly object.
- Win32::CLR->has_member("TYPE", "NAME", [$MEMBER_TYPE])
-
Checks TYPE has member NAME. $MEMBER_TYPE is System.Reflection.MemberTypes constants delimited by commas. Default is Method, Field, Property, Event.
if ( Win32::CLR->has_member("System.String", "Length", "Field, Property") ) { print "System.String has Length\n"; }
INSTANCE METHODS
Win32::CLR instance has similar methods to class methods.
$obj->call_method("NAME", @PARAMS)
$obj->get_field("NAME", [$INDEX])
$obj->set_field("NAME", [$INDEX, ] $PARAM)
$obj->get_property("NAME", [$INDEX])
$obj->set_property("NAME", [$INDEX, ] $PARAM)
$obj->get_value("NAME", [$INDEX])
$obj->set_value("NAME", [$INDEX, ] $PARAM)
$obj->add_event("NAME", $DELEG)
$obj->remove_event("NAME", $DELEG)
$obj->has_member("NAME", [$MEMBER_TYPE])
- $obj->get_addr()
-
Returns object address. Can be used for Inside-out class.
- $obj->derived_from("TYPE")
-
Like UNIVERSAL::isa, returns $obj is derived from TYPE.
- $obj->to_string()
-
Converts $obj to perl primitive string.
CREATING GENERIC INSTANCE
If you want to create generic instance, use optional parameter type enclosed by "<>".
my $name = "System.Collections.Generic.Dictionary<System.String, System.Int32>";
my $dict = Win32::CLR->create_instance($name);
Also System.Type.GetType form can be used.
my $name = "System.Collections.Generic.Dictionary`2[System.String, System.Int32]";
my $dict = Win32::CLR->create_instance($name);
GENERIC TYPE EXAMPLE
"Generic< Generic<Type1, Type2>, Type3 >" # recursive
"Generic< Generic`2[Type1, Type2], Type3 >" # mixing
my $type = <<"TYPE"; # assembly qualified form
System.Collections.Generic.Dictionary<
[
System.String, mscorlib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089
],
System.Int32
>, mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
TYPE
# creating generic delegate
my $deleg = Win32::CLR->create_delegate(
"System.Action<System.String>",
sub { print $_[0] }
);
CALLING GENERIC METHOD
Like creating generic type, generic method can be used.
$obj->call_method("method<System.String>", @params);
TYPE CONVERSION
Win32::CLR automatically converts primitive value between .net and perl.
.net -> perl
Boolean -> perl bool
SByte, Int16, Int32, Int64 -> perl int
Byte, UInt16, UInt32, UInt64 -> perl unsigned int
Single, Double -> perl double
Char, String, Decimal -> perl string(utf8 flag on)
null(nullptr) -> perl undef
other -> perl Win32::CLR instance
perl -> .net
Win32::CLR instance -> Object
perl int -> Int32 -> cast target
perl unsigned int -> UInt32 -> cast target
perl string -> Char, String, Decimal
perl double -> Double -> cast target
perl undef -> null(nullptr)
OVERLOAD
Following operators are overloaded.
"" bool == != + - * / % > >= < <= ++ --
my $dt1 = Win32::CLR->create_instance("System.DateTime", 2007, 8, 9, 10, 11, 12);
my $dt2 = Win32::CLR->create_instance("System.DateTime", 2008, 8, 9, 10, 11, 12);
print "$dt1";
$dt1 == $dt1;
$dt1 != $dt2;
$dt > $dt2;
$dt < $dt2;
If you want compare instance equality, use get_addr method.
$dt->get_addr() == $dt->get_addr()
AUTOLOAD
When calling method named /^(get|set)_\w+/, it is converted to get_value or set_value. If not /^(get|set)_/, converted to call_method. Underscore is ignored and name is ignorecase.
$obj->get_year() -> $obj->get_value("Year")
$obj->get_y_e_Ar() -> $obj->get_value("Year")
$obj->set_year(1) -> $obj->set_value("Year", 1)
$obj->add_years(2) -> $obj->call_method("AddYears", 2)
$obj->AddYears(2) -> $obj->call_method("AddYears", 2)
$obj->aDd__yEaRs(2) -> $obj->call_method("AddYears", 2)
BUGS AND WARNINGS
More tests and documents are required.
COPYRIGHT & LICENSE
Copyright 2007 Toshiyuki Yamato, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.