Возврат объекта perl из другого класса perl в C# с использованием PerlNET
У меня есть два модуля Perl, которые я хочу представить как типы объектов для C#. Один из них создает объекты другого типа и возвращает его, используя метод, как показано ниже. Я включаю ссылку на Type2.dll в Type1.dll и ссылаюсь на них обоих в C#. Как показывает код, я могу создать объект Type2 непосредственно из C#, но я не могу вернуть объект Type2, который был создан методом в Type1. Есть идеи?
(Перекрестная публикация с 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;
2 ответа
Так как это было перекрестно опубликовано на community.activestate.com и там ответили, я скопирую ответ оттуда сюда, но я урежу его, потому что считаю его слишком длинным.
Главная проблема в том, как ты это написал, Type2
не считается типом, а вызов Type2->new()
не переводится в вызов конструктора (но вызывается статическим методом).
Следующие изменения в вашем коде исправят это:
- В Type2.pm измените
package Type2
вpackage Sample::Type2
, Это делает Type2 типом, а Sample - пространством имен. - В Type1.pm аналогичным образом меняются
package Type1
вpackage Sample::Type1
, - В Type1.pm измените
use Type2;
вuse namespace "Sample";
, Это импортирует Type2 как тип.
Размещенный код C# работает как требуется после этих изменений.
Я также обнаружил, что я могу создать один файл, как это:
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. Я создал один файл pm для своей сборки на C#, и в него я включил определения интерфейса для доступа к устаревшим методам библиотеки и набор специфических методов.NET для свойств и преобразования сложных возвращаемых значений структуры данных хеш / массива Perl в Структуры данных Hashtable и Array/ArrayList.