Передача COM-объекта из C# в Perl с использованием PerlNET
Я пытаюсь передать COM-объект из кода C# в Perl.
На данный момент я обертываю свой код Perl с помощью PerlNET (PDK 9.4; ActiveState), и я определил простую подпрограмму (+ обязательное объявление pod) в Perl для передачи объектов из C# в обернутый модуль Perl.
Кажется, что объекты, которые я передаю, не распознаются правильно как объекты COM.
Пример:
В C# (.NET 4.0) ScriptControl используется для загрузки простого класса из файла, написанного на VBScript.
var host = new ScriptControl();
host.Language = "VBScript";
var text = File.ReadAllText("TestScript.vbs");
host.AddCode(text);
dynamic obj = host.Run("GetTestClass");
Что я получаю (obj
) имеет тип System.__ComObject
, Когда я передаю его в мою сборку Perl/PerlNET и пытаюсь вызвать метод Xyz()
в Perl я получаю следующее (во время выполнения) исключение:
Can't locate public method Xyz() for System.__ComObject
Однако, если я делаю более или менее то же самое в Perl, это работает. (В следующем случае, передавая только содержимое моего файла.vbs в качестве параметра.) Я даже могу использовать скрипт управления:
sub UseScriptControl {
my ($self, $text) = @_;
my $script = Win32::OLE->new('ScriptControl');
$script->{Language} = 'VBScript';
$script->AddCode($text);
my $obj = $script->Run('GetTestClass');
$obj->Xyz();
}
Теперь звоню Xyz()
на obj
работает нормально (используя Win32::OLE).
В обоих случаях я использую:
use strict;
use Win32;
use Win32::OLE::Variant;
Другой подход:
Я могу вызвать методы с помощью InvokeMember
класса System.Type
если я точно укажу , какую перегрузку я хочу использовать и какие типы я передаю:
use PerlNET qw(typeof);
typeof($obj)->InvokeMember("Xyz",
PerlNET::enum("System.Reflection.BindingFlags.InvokeMethod"),
PerlNET::null("System.Reflection.Binder"),
$obj,
"System.Object[]"->new());
Использование этого подхода будет означать переписывание всего упакованного модуля Perl. И используя этот синтаксис..
Теперь мне интересно, теряю ли я преимущества динамического ключевого слова в.NET 4.0 и динамических характеристик Perl (с Win32:: OLE), используя PerlNET с COM-объектами.
Кажется, мое предпочтительное решение сводится к тому, чтобы имитировать поведение dynamic
Ключевое слово в C#/.NET 4.0.
Или, лучше, найти какой-то способ преобразования переданного COM-объекта в нечто, что будет признано совместимым с Win32::OLE
, Может быть, извлечь некоторую информацию о __ComObject
чтобы он был правильно идентифицирован как COM-объект.
Я должен добавить, что я также разместил сообщение на сайте обсуждения PDK (но пока не получил никакого ответа): http://community.activestate.com/node/18247
Я также опубликовал его в PerlMonks - поскольку я не совсем уверен, является ли это вопросом Perl или C# /.NET: http://www.perlmonks.org/?node_id=1146244
Я был бы очень признателен за любую помощь - или посоветовать, где искать дальше.