tags:

views:

65

answers:

1

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?

+1  A: 

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;
Minh Le