3

これは、Eric Lippert、または JScript エンジンの実装に精通している Microsoft の誰かに対する質問です。

私はこれを行うことができます:

var obj = new ActiveXObject("My.ProgId");
var methods = GetMethodsViaMagic(obj);

?

(COM タイプが IDispatch をサポートしている場合)

もしそうなら、どのようにGetMethodsViaMagic()見えますか?


編集- もちろん、私が最初に試したのはfor...inループでしたが、ActiveX オブジェクトで定義されたメソッドとプロパティでは機能しません。少なくとも、私が .NET で定義し、ComVisible.


C# では、次のように IDispatch を定義できます。

 [Guid("00020400-0000-0000-c000-000000000046"),
  InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 public interface IDispatch
 {
     int GetTypeInfoCount();
     System.Runtime.InteropServices.ComTypes.ITypeInfo
         GetTypeInfo([MarshalAs(UnmanagedType.U4)] int iTInfo,
                     [MarshalAs(UnmanagedType.U4)] int lcid);

     [PreserveSig]
     int GetIDsOfNames(ref Guid riid,
                       [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] rgsNames,
                       int cNames,
                       int lcid,
                       [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);

     [PreserveSig]
     int Invoke(int dispIdMember,
                ref Guid riid,
                [MarshalAs(UnmanagedType.U4)] int lcid,
                [MarshalAs(UnmanagedType.U4)] int dwFlags,
                ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
                [Out, MarshalAs(UnmanagedType.LPArray)] object[] pVarResult,
                ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
                [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] pArgErr);
 }

次に、次のようなことができます。

    var idispatch = (IDispatch) comObject ;
    System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo =
        idispatch.GetTypeInfo(0, 0);

    System.Runtime.InteropServices.ComTypes.FUNCDESC funcDesc;
    string strName, strDocString, strHelpFile;
    int dwHelpContext;

    typeInfo.GetFuncDesc(i, out pFuncDesc);// i = 1, 2, 3...
    funcDesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC)
        Marshal.PtrToStructure(pFuncDesc,
                               typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));

...そして、関数 (メソッド) 名、および引数の数などを取得します。

ActiveX (COM IDispatch) オブジェクトに対して、JScript でそのようなことを行うことはできますか?

4

3 に答える 3

6

まず、私は10年以上JScriptに取り組んでいないことを覚えておいてください。その間にエンジンが変わって、私の記憶が薄れてしまいました。

私の記憶と知識の限りでは、for-inループは、オブジェクトがIDispatchExを実装している場合は機能しますが、オブジェクトがIDispatchを実装している場合は機能しません。

JScriptプログラムがディスパッチオブジェクトに関連付けられた型情報から入手できる情報を使用してプロパティを列挙できるようなメカニズムを常に追加したかったのですが、実際にコードを記述したことはないと思います。

于 2011-08-22T15:30:11.647 に答える
3

私が見つけたのは、ComVisible .NET オブジェクトに IReflect を実装していればfor...in、Javascriptループを使用してメソッドとプロパティを列挙できることです。

IReflectは、CCW 全体で IDispatch としてマーシャリングされます。

于 2011-08-22T13:00:09.370 に答える
2

あなたはできるはずです

var methods = [];
for( var property in obj ) {
    if( obj.hasOwnProperty(property) && typeof obj[property] === 'function' ) {
        methods.push(property);
    }
}

methods配列にはメソッド名が含まれます。問題のオブジェクトが何らかのコンストラクターのインスタンスである場合は、hasOwnPropertyチェックをドロップすることをお勧めします。これにより、プロトタイプ チェーンではなく、obj 自体で定義されているプロパティ/メソッドのみを参照するようにすべてが制限されるためです。

引数の数については、(ドメニックがコメントで指摘しているように)関数自体.lengthプロパティを使用できます。

のすべてのメソッドの引数の名前と数の両方を取得するには、次のようにしobjます。

var methods = [];
for( var property in obj ) {
    if( obj.hasOwnProperty(property) && typeof obj[property] === 'function' ) {
        methods.push({
            name: property,
            args: obj[property].length
        });
    }
}

そして、それぞれが からのメソッドの名前と引数の数を含むオブジェクト リテラルの配列を取得しますobj


編集:この回答を最初に書いたとき、引数の名前(単に数ではなく)を取得することを考えていたため、それらの名前を取得するためのかなりハッキーなコードが含まれていました。誰かが興味を持っている場合に備えて、 Prototype.jsから改作して恥知らずに盗んだコードをここに示します) 。

function argumentNames(func) {
  var names = func.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
    .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
    .replace(/\s+/g, '').split(',');
  return names.length == 1 && !names[0] ? [] : names;
}

関数/メソッドをその関数に渡すと、引数名が返されます…多分. 返されたオブジェクトが完全なホスト オブジェクトである場合、そのメソッド/関数は で読み取れない可能性がありますtoString()。通常、toString()メソッド/関数の実際のソース コードを返します (argumentNames関数はそれを正規表現で解析します) が、ネイティブ コードの場合は、ソースではなく文字列 "native code" または何かを返すだけです。コード。

于 2011-08-21T22:52:56.417 に答える