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.crea
te***系で、
「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を何段も使っ
てやっとできた感じです。
これを統一するのは難しいかもしれません。

[ ]
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版だと動作しましたが、(dynami
cの代わりにこの「独自実装IDispatchっぽい何か」でも動作するw)

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

[ ]