2010-04-21 4 views
9

Mam dwa moduły Perla, które chcę wystawić jako typy obiektów do C#. Jeden z nich tworzy obiekty innego typu i zwraca je za pomocą metody pokazanej poniżej. Załączam odwołanie do Type2.dll w Type1.dll i odniesienia do nich zarówno w języku C#. Jak pokazuje kod, mogę skonstruować obiekt Type2 bezpośrednio z C#, ale nie mogę zwrócić obiektu Type2, który został skonstruowany przez metodę w Type1. Jakieś pomysły?Zwróć obiekt perl z innej klasy Perla do C# przy użyciu PerlNET

(Cross-pisał z http://community.activestate.com/forum/return-perl-object-different-perl-class-c)

C#:

Type1 obj1 = new Type1(); // Works 
Type2 test = new Type2(); // Works 
Type2 obj2 = obj1.make2(); 
// Fails: System.InvalidCastException: Unable to cast object of type 
// 'PerlRunTime.SV' to type 'Type2' at Type1.make2() 

Perl: Type1.pm

package Type1; 

use strict; 
use Type2; 

=for interface 
    [interface: pure] 
    static Type1(); 
    Type2 make2(); 
=cut 

sub new { 
    my $class = shift; 
    return bless {}, $class; 
} 

sub make2 { 
    my $this = shift; 
    return Type2->new(); 
} 

1; 

Perl: Type2.pm

package Type2; 

use strict; 

=for interface 
    [interface: pure] 
    static Type2(); 
=cut 

sub new { 
    my $class = shift; 
    return bless {}, $class; 
} 

1; 
+0

FYI: Używam zestawu ActiveState Perl Dev Kit 8.2.1, PerlNET i .NET 3.5. – DougWebb

+0

Lepiej dodać to w pytaniu. – Space

Odpowiedz

2

Od tego został przekierowany do community.activestate.com i tam tam otrzymałem odpowiedź, skopiuję odpowiedź od tego miejsca, ale usuniemy ją, ponieważ uważam, że jest za długa.

Głównym problemem jest to, że sposób, w jaki to napisał, Type2 nie jest uważany za typ i nazywając Type2->new() nie przekłada się na wywołanie konstruktora (ale statycznej metody wywołania).

następujące zmiany w kodzie to naprawić:

  • W Type2.pm zmień package Type2 do package Sample::Type2. To sprawia, że ​​Type2 jest typem i Sample a namespace.
  • W Type1.pm podobnie zmień package Type1 na package Sample::Type1.
  • W Type1.pm zmień use Type2; na use namespace "Sample";. To importuje Type2 jako typ.

Opublikowany kod C# działa zgodnie z wymaganiami po tych zmianach.

1

Ja również okazało się, że można utworzyć jeden plik tak:

package Type2; 

=for interface 
    [interface: pure] 
    static Type2(); 
=cut 

require Type2; 


package Type1; 
use Type2; 

=for interface 
    [interface: pure] 
    static Type1(); 
    Type2 make2(); 
=cut 

Wtedy mój Type1.pm i pliki Type2.pm są takie same jak wcześniej, ale bez POD interfejsu. Przy tej konfiguracji plc tworzy pojedynczy plik dll, który zawiera obie klasy, a klasa Type1 jest w stanie tworzyć i zwracać instancje Type2.

To faktycznie okazało się wygodniejsze dla mnie, ponieważ moje klasy Type1 i Type2 są częścią starszej biblioteki, którą chcę udostępnić kodowi C#, nie wprowadzając w nich szczegółowych zmian związanych z .NET. Stworzyłem jeden plik pm dla mojego zestawu C#, a do niego dodałem definicje interfejsów do uzyskiwania dostępu do starszych metod biblioteki i kilka specyficznych metod .NET dla właściwości i konwersji złożonych wartości zwracanych przez strukturę danych mieszających Perla/tablicy do Struktury danych Hashtable i ArrayList/ArrayList.

Powiązane problemy