2010-04-21 30 views
9

我有两个Perl模块,我想将它们作为对象类型公开为C#。其中一个构造另一个类型的对象,并使用如下所示的方法返回它。我在Type1.dll中包含对Type2.dll的引用,并在C#中引用它们。如代码所示,我可以直接使用C#构造Type2对象,但无法返回由Type1中的方法构造的Type2对象。有任何想法吗?使用PerlNET将不同的perl类中的perl对象返回到C#

(从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

仅供参考:我正在使用ActiveState Perl Dev Kit 8.2.1,PerlNET和.NET 3.5。 – DougWebb 2010-04-21 18:09:39

+0

最好在你的问题中加上这个。 – Space 2010-04-26 10:20:35

回答

2

由于这被交叉发布到community.activestate.com已经在那里回答了,我会把答案从那里复制到这里,但我会把它缩小,因为我认为它太冗长。

的主要问题是,你写的方式,Type2不被认为是,并呼吁Type2->new()并没有转化为构造函数调用(但一个静态方法调用)。

以下到您的代码更改解决此问题:

  • 在Type2.pm,改变package Type2package Sample::Type2。这使得Type2成为一个类型,并为一个名称空间Sample。
  • 在Type1.pm中,同样将package Type1更改为package Sample::Type1
  • 在Type1.pm中,将use Type2;更改为use namespace "Sample";。这导入Type2作为类型

发布的C#代码在这些更改后按需要工作。

1

我还发现,我可以创建一个文件是这样的:

package Type2; 

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

require Type2; 


package Type1; 
use Type2; 

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

然后我Type1.pm和Type2.pm文件都和以前一样,但没有接口POD。 使用此设置,plc创建一个包含两个类的单个dll,并且Type1类能够创建并返回Type2的实例。

这实际上对我来说更加方便,因为我的Type1和Type2类是我希望提供给C#代码的遗留库的一部分,而无需对它们进行广泛的.NET特定更改。我为我的C#程序集创建了一个pm文件,其中包含了访问遗留库方法的接口定义以及一些.NET特定的属性方法,并将复杂的Perl哈希/数组数据结构返回值转换为散列表和Array/ArrayList数据结构。