9

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

(这是从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()

珀尔: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;

珀尔:Type2.pm

package Type2;

use strict;

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

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

1;
4

2 回答 2

2

由于这是交叉发布到community.activestate.com并已在那里得到回答,我会将答案从那里复制到这里,但我会删减它,因为我认为它太长了。

主要问题是您编写它的方式Type2不被视为type,并且调用Type2->new()不会转换为构造函数调用(而是静态方法调用)。

对您的代码进行以下更改可解决此问题:

  • 在 Type2.pm 中,更改package Type2package Sample::Type2. 这使得 Type2 成为类型,而 Sample 成为命名空间。
  • 在 Type1.pm 中,同样更改package Type1package Sample::Type1.
  • 在 Type1.pm 中,更改use Type2;use namespace "Sample";. 这会将 Type2 作为type导入。

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

于 2010-05-10T16:28:29.830 回答
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 类是遗留库的一部分,我希望在不对它们进行大量特定于 .NET 的更改的情况下将其提供给 C# 代码。我为我的 C# 程序集创建了一个 pm 文件,其中包含用于访问遗留库方法的接口定义和一组用于属性的 .NET 特定方法,并将复杂的 Perl 哈希/数组数据结构返回值转换为Hashtable 和 Array/ArrayList 数据结构。

于 2010-05-10T21:12:27.723 回答