Monday, April 11, 2011

How do I raise an event in a PerlNet module?

I’m using PDK 7.3 as a development tool for developing an application using both .NET and Perl.

I want to build Perl into an .NET compatible dll and this module can raise an event that a .NET GUI application can handle.

I can't find any documentation about it. As far as I know PDK 7.3 does not support implementing delegates.

Is this true? Do I have any options?

From stackoverflow
  • I wrote an email to Jan Dubois from ActiveState company. He suggested a way to implement the callback mechanism for it.

    Hope this help.

    ===========================================

    Hi Minh,

    You can implement a delegate just fine in PerlNET, you just cannot declare new delegate types in it.

    I've attached some sample code that defines a delegate in Perl and later passes it to C#. You'll need to separate the pieces into individual files and compile them manually; the code is ripped out of some regression tests and you won't have the rest of the test harness to run it as is. (Looks like the formatting also got chopped a little, but the intend of the code should still be clear).

    Cheers,

    -Jan

    #!./perl -w
    
    # Define some properties and fields in perl and try to access them.
    print "1..1\n";
    require 'setup.pl';
    csc("-target:library DB.cs");
    cleanup("DB.dll");
    plc(-target => "library", -out => "P.dll", -r => "DB.dll", "P.pm");
    csc("test.cs -r:DB.dll -r:P.dll");
    cleanup("./test.exe");
    my $res = `./test.exe`;
    print "----\n$res----\n";
    print "not " unless $res eq <<'EOT';
    XXX 65
    XXX 66
    XXX 67
    XXX 68
    XXX 69
    XXX 70
    XXX 71
    XXX 4.2
    XXX 4.30000019073486
    XXX 4.4
    XXX a
    XXX 1
    XXX ""
    XXX Hi
    XXX <undef>
    EOT
    print "ok 1\n";
    __END__
    

    ======================= test.cs =====================

    using System;
    
    class main : IPrint
    {
        public static void Main(string[] args)
        {
             P p = new P(new main());
             DataBase db = new DataBase();
             db.Add((byte)65);
             db.Add((short)66);
             db.Add((int)67);
             db.Add((long)68);
             db.Add((uint)69);
             db.Add((ushort)70);
             db.Add((ulong)71);
             db.Add(4.2D);
             db.Add(4.3F);
             db.Add(4.4M);
             db.Add('a');
             db.Add(true);
             db.Add(false);
             db.Add("Hi");
             db.Add(null);
             db.Scan(p.handler);
        }
    
        main() {}
    
        public void print(string s) {
             Console.WriteLine(s);
    
       }
    }
    

    ======================= DB.cs =====================

    using System;
    using System.Collections;
    
    public delegate void ProcessItem(Object i);
    public class DataBase : ArrayList {
        public DataBase() {}
        public void Scan(ProcessItem handler) {
    
            foreach (object o in this) {
                handler(o);
            }
        }
    
    }
    
    public interface IPrint {
        void print(string s);
    
    }
    

    ======================= P.pm =====================

    package P;
    
    =for interface
    
    interface ProcessItem;  # a delegate type
    interface IPrint;
    interface System.Object;
    
    interface P {
        static P P(IPrint ip);
        readonly ProcessItem handler;
        void x(System.Object y);
        private field IPrint ip;
    }
    
    =cut
    
    sub P {
        my($self, $ip) = @_;
        $self->{ip} = $ip;
    }
    
    sub handler {
        my $self = shift;
        return ProcessItem->new($self, "x");
    }
    
    sub x {
        my($self, $obj) = @_;
        $obj = "<undef>" unless defined $obj;
        $obj = '""' unless length $obj;
        $self->{ip}->print("XXX $obj");
    }
    
    1;
    

0 comments:

Post a Comment