[ 新規に投稿する ]

jsmodeとcreateobjectと引数や返値の透過使用No.11605
こみやんま さん 24/03/21 11:08 [ コメントを投稿する ]
  若干話が難し目になるかもしれませんが、
jsmodeがJScriptかWebView2かで、同じCOMオブジェクトであっても
引数(や返り値)として渡せる型が違うのを吸収できないか、といった質問です。


■jsmodeがJScriptの場合

-- Class1.cs .NET4.xの COM参照可のdllとしてコンパイル------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary14
{
    public interface IClass1 // 外部から利用できるメソッドに対してinterfaceの定義が必須になる。
    {
        void CheckObj(dynamic obj);
        void CheckFunc(dynamic func);
        void CheckHGFunc(dynamic obj);
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)] // これは必須
    [Guid("3B0C3A24-F1C9-4ECA-BC45-0BFAF98CDC0B")]
    public class Class1 : IClass1
    {
        public void CheckObj(dynamic obj)
        {
            System.Diagnostics.Trace.WriteLine((int)obj.bbb);
        }

        public void CheckFunc(dynamic func)
        {
            int sum = func(100, 200);
            System.Diagnostics.Trace.WriteLine(sum);
        }

        public void CheckHGFunc(dynamic message_func)
        {
            message_func("OK");
        }

    }
}

-- aaa.mac ------------

js {
    var obj = createobject(currentmacrodirectory() + @"\ClassLibrary14.dll", "ClassLibrary14.Class1");
    debuginfo(2);
 
    var myobj = {
       "bbb" : 3
    };
 
    function myfunc(a, b) { return a + b; }
    obj.CheckObj(myobj); // オブジェクトをC#のdllに渡す
    obj.CheckFunc(myfunc); // 関数をC#のdllに渡す
    obj.CheckHGFunc(hg.message); 
}

--------------------------------
これはhmJSやhmV8と同じで、機能していまして、
JS上の「オブジェクト」や「関数」などをそのままC#のdllに渡し、そのまま「あるがまま」使うことができます。
(正直これはめっちゃ強力!! JavaScriptの関数をとても自然にコールバックできます!!)
System.__ComObject を C#のdynamic がうまくディスパッチしていていると言えます。







■jsmodeがWebView2の場合

一方でWebView2の場合は、同様の上のCOMクラスだと、引数として渡せるものは「数値」「文字列」「配列(おそらく3深まで?)」であり、
なぜか、「関数」や「オブジェクト」を渡しても上の記述ではうまくディスパッチされません。

一方で、秀丸のjsmodeを見ると、WebView2でもhidemaru.runProcessやhidemaru.create***系で、
「javascriptの関数を引数とする」COMオブジェクトのメソッドが定義されているので、
普通に秀丸担当さんの方では、C++で上手くディスパッチできているものと思います。

その辺の記述ってC++でどうなっていますか?

C++側から、CoreWebView2.AddHostObjectToScript に登録した COMのメソッドでないと、関数やオブジェクトは
引数や返り値にできないのかなぁ...
[ ]
RE:11605 hg. ⇒ hidemaruGlobal.No.11606
こみやんま さん 24/03/21 11:09 [ コメントを投稿する ]
  obj.CheckHGFunc(hg.message);  は

obj.CheckHGFunc(hidemaruGlobal.message); です
[ ]
RE:11605 jsmodeとcreateobjectと引数や返値の透過使用No.11608
秀丸担当 さん 24/03/21 17:10 [ コメントを投稿する ]
  JavaScript側から呼ばれる関数は、確かにややこしいです。
JScriptは素直に動いてくれていたと思うのですが、WebView2はそのままだとできなかったと思います。
とにかくそうなるようにC++でゴリゴリ書くのと、WebView2側はPromiseを何段も使ってやっとできた感じです。
これを統一するのは難しいかもしれません。
[ ]
(発言者削除)No.11609
こみやんま さん 24/03/21 18:31
 
[ ]
RE:11608 jsmodeとcreateobjectと引数や返値の透過使用No.11610
こみやんま さん 24/03/21 18:32 [ コメントを投稿する ]
  https://github.com/MicrosoftEdge/WebView2Feedback/issues/347
https://github.com/MicrosoftEdge/WebView2Feedback/issues/918

うーん、このあたりで「WebView2上のJS空間内の関数」を「C#空間」へと引数で渡して、それを「C#空間」内で実行できないか、的な議論があって、
そう容易ではない、みたいな感じっぽいですねぇ。
(JScript版があれほど簡単でかつ綺麗になってるのが異様といえば異様ですがw)

対象のstatic class InvokeMemberHelper はJScript版だと動作しましたが、(dynamicの代わりにこの「独自実装IDispatchっぽい何か」でも動作するw)

WebView2版の方は動作しないですねぇ。
というかここにあるような記事とは異なり、C#の引数として渡ってきている
時点でIDispatchではあるけれども、何も中身がないっていうかメソッドもプロパティも何もないIDispatchがくっ付いているっていうか...
[ ]

[ 新規に投稿する ]