6

モノ埋め込み呼び出しを使用してジェネリック List<String> オブジェクトを作成するにはどうすればよいですか? List の MonoClass を取得できます。

MonoClass* list = mono_class_from_name(mscorlibimage,
     "System.Collections.Generic", "List`1");

そして私はそこにあることをドキュメントで見ます

mono_class_from_generic_parameter(MonoGenericParam*...)

しかし、MonoGenericParam を取得する場所と方法がわかりません。それとも、mono_class_from_name の有効な名前を作成する必要がありますか? これは少し遅くなる可能性があると思いますが、今のところ受け入れます。私は試した

MonoClass* list = mono_class_from_name(mscorlib::get().image, "System.Collections.Generic", "List`1[System.String]");

しかし運がない。

アップデート:

OK、方法を見つけました。それでも、このハックは私にはあまりにも汚いように見えるので、公式の方法があるかどうかを確認したいと思います.

基本的に、ジェネリック メソッドの mono ソースを検索し、mono_class_bind_generic_parameters を見つけました ( https://raw.github.com/mono/mono/master/mono/metadata/reflection.cを参照)。それを使用するには、.so に加えて libmono-2.0.a にリンクする必要がありました。しかし、それはうまくいきました:

extern "C" MonoClass*
mono_class_bind_generic_parameters(MonoClass *klass, 
    int type_argc, MonoType **types, bool is_dynamic);

MonoClass* list = mono_class_from_name(mscorlib::get().image,
    "System.Collections.Generic", "List`1");
MonoClass* strcls = mono_class_from_name(mscorlib::get().image, "System", "String");
printf("str class: %p\n", strcls);
MonoType* strtype = mono_class_get_type(strcls);
printf("str type: %p\n", strtype);
MonoType* types[1];
types[0] = strtype;
list = mono_class_bind_generic_parameters(list, 1, types, false);
printf("list[string] class: %p\n", list);
MonoObject* obj = mono_object_new(domain, list);
printf("list[string] created: %p\n", obj);

.a にリンクしたくない場合は、これらのメソッドのソース (UPDATE: ほとんどそうではありません) を取得して再実装 (メタデータなどを解析) できると思いますが、もっと簡単な方法があるのではないかと思います。モノのドキュメントは、以前のように何も答えません。

更新: このスレッドを見つけました: http://mono.1490590.n4.nabble.com/Embedded-API-Method-signature-not-found-with-generic-parameter-td4660157.html埋め込み API が存在しないと思われる私が望むもののために(つまり、mono_class_bind_generic_parametersを公開する必要はありません)。誰かがそれが正しいことを証明できますか? ところで、そのメソッドでは、MonoReflectionType* を取得し、そこから MonoType* を取得する方法はありません - 構造体から ->type を取得するのと同じくらい簡単ですが、これは内部であり、関数を介してアクセスするのは内部です。Mono Embedded は、代わりに「Mono Internal」と呼ぶ必要があります。

更新: 別の方法は、内部構造のコピーを使用して mono_class_inflate_generic_type をハックすることです。

struct _MonoGenericInst {
        uint32_t id;                       /* unique ID for debugging */
        uint32_t type_argc    : 22;        /* number of type arguments */
        uint32_t is_open      :  1;        /* if this is an open type */
        MonoType *type_argv [1];
};

struct _MonoGenericContext {
        /* The instantiation corresponding to the class generic parameters */
        MonoGenericInst *class_inst;
        /* The instantiation corresponding to the method generic parameters */
        void *method_inst;
};

   _MonoGenericInst clsctx;
   clsctx.type_argc = 1;
   clsctx.is_open = 0;
   clsctx.type_argv[0] = mono_class_get_type(System::String::_SClass());
   MonoGenericContext ctx;
   ctx.method_inst = 0;
   ctx.class_inst = &clsctx;
   MonoType* lt = mono_class_inflate_generic_type(
      mono_class_get_type(System::Collections::Generic::List<System::String>::_SClass()),
      &ctx);

これは .a への静的リンクを必要としませんが、さらに悪いハックです。そして、 mono_class_inflate_generic_type は非推奨としてマークされています-これが非推奨である場合、どちらが最新のものですか?

4

1 に答える 1