PowerShellのなにが便利って、.NETアセンブリが読み込めちゃうので、
もう何でもかんでもできてしまうところ。
Windows7から標準で入っているので、業務用ツール作るのに最近よく使う。
それは置いといて…
表題の、引数が配列のメソッドが呼べない件。
PowerShell上で関数やスクリプト作った際に、引数が配列なのは問題ない。
エラーとなるのは、.NETアセンブリのメソッドの引数が配列だった場合だ。
たとえば、以下の様なクラスライブラリがあったとする。(C++/CLIで申し訳ない…)
using namespace System;
namespace TEST {
public ref class CRcvArray {
cli::array<int> ^m_ary;
public:
CRcvArray(cli::array<int> ^ary) : m_ary(ary) {}
int GetLen() { return m_ary->Length; }
};
}
このアセンブリを、仮に "C:\CRcvArray.dll"
に置いたとして、
[Reflection.Assembly]::LoadFile("C:\CRcvArray.dll")
$o = New-Object TEST.CRcvArray(@(1,2,3))
を実行すると、
New-Object : "CRcvArray" のオーバーロードで、引数の数が "3" であるものが見つかりません。
発生場所 行:1 文字:16
+ $o = New-Object <<<< TEST.CRcvArray(@(1,2,3))
+ CategoryInfo : InvalidOperation: (:) [New-Object]、MethodException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
と言うエラーが出てしまう。
どうやら、配列が引数の数に変換されてしまうようだ。
…とすると、あらかじめ長さ1の配列に入れてしまえば良さそう。
かといって、
$o = New-Object TEST.CRcvArray(@(@(1,2,3)))
とすると、勝手に配列が結合されてしまうので、うまくいかない。
(配列の宣言時に、配列を入れると、そのコピーが作成されるため。)
これを回避して実行するには、
[Reflection.Assembly]::LoadFile("C:\CRcvArray.dll")
$o = New-Object TEST.CRcvArray(@(,@(1,2,3)))
$o.GetLen()
としてやればよい。
カンマをちょこっと加えるだけでちゃんと動くようになる。
ピンバック: Tweets that mention Aqua Ware つぶやきブログ » [powershell]引数が配列のメソッドが呼べない -- Topsy.com