4

C# コードから Perl に COM オブジェクトを渡そうとしています。
現在、Perl コードを PerlNET (PDK 9.4; ActiveState) でラップしており、C# からラップされた Perl モジュールにオブジェクトを渡すために、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 アセンブリに渡し、Perl でメソッドを呼び出そうとするとXyz()、次の (実行時) 例外が発生します。

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;

別のアプローチ:使用するオーバーロードと渡す型を正確に指定すると、of クラス
を使用してメソッドを呼び出すことができます。InvokeMemberSystem.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 モジュール全体を書き直すことになります。そして、この構文を使用して..

PerlNET と COM オブジェクトを使用することで、.NET 4.0 の dynamic キーワードの利点と Perl の動的な特性 (Win32::OLE を使用) の両方を失うのではないかと考えています。

dynamic私の好みの解決策は、C#/.NET 4.0 のキーワードの動作を模倣する何らかの方法に集約されるようです。

または、渡された COM オブジェクトを と互換性があると認識されるものに変換する何らかの方法を見つけることをお勧めしWin32::OLEます。__ComObjectCOMオブジェクトとして正しく識別されるように、の情報を抽出するかもしれません。

PDK ディスカッション サイトにも投稿したことを追加する必要があります (ただし、まだ応答がありませんでした): http://community.activestate.com/node/18247
PerlMonks にも投稿しました。これがPerlまたはC#/.NETの質問であるかどうかを確認してください: http://www.perlmonks.org/?node_id=1146244

助けていただければ幸いです-または、さらに調べる場所についてアドバイスしてください。

4

0 に答える 0