gpt4 book ai didi

c# - 单声道嵌入,从 C 调用 C# 泛型方法

转载 作者:太空狗 更新时间:2023-10-29 15:07:12 25 4
gpt4 key购买 nike

我无法弄清楚如何从 C 调用泛型方法(静态和非静态)。

最大的罪魁祸首是调用泛型方法基本上没有记录,mono 存储库中没有示例,但文档中提到这是可能的:

If you want to invoke generic methods, you must call the method on the "inflated" class, which you can obtain from the mono_object_get_class()


MonoClass *clazz;
MonoMethod *method;

clazz = mono_object_get_class (obj);

/*
* If there are more Add methods declared, you
* may use mono_method_desc_search_in_class (clazz, ":Add(T)"),
* you must substitute ":Add(T)" with the correct type, for example
* for List<int>, you would use ":Add(int)".
*/
method = mono_class_get_method_from_name (clazz, "Add", 1);
mono_runtime_invoke (method, obj, args, &exception);

不幸的是,这并没有多大帮助,因为它没有显示完整的示例,而且无论我做什么(使用 mono_object_get_class 或不使用),我最终都会收到警告,然后在调用时崩溃通用方法。

* Assertion: should not be reached at marshal.c:4315
SIGABRT stracktrace...

下面是示例 C# 类和调用它的 C 代码。调用非泛型方法工作得很好,但我不知道如何调用泛型方法。如果有任何有用的提示,我将不胜感激。

CSharp 示例

namespace foo {
class MainClass {
public static void Main(string[] args) {
Console.WriteLine("Main");
}

public void GenericMember<T>(T t) {
Console.WriteLine(t);
}

public static void GenericStatic<T>(T t) {
Console.WriteLine(t);
}


public void NonGenericMember(string t) {
Console.WriteLine(t);
}

public static void NonGenericStatic(string t) {
Console.WriteLine(t);
}
}
}

示例 C

#include <mono/jit/jit.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/class.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/image.h>
#include <mono/metadata/object.h>
#include <mono/metadata/debug-helpers.h>

int main(int argc, char **argv) {
mono_config_parse(NULL);

MonoDomain *domain = mono_jit_init_version("app", "v4.0.30319");
MonoAssembly *assembly = mono_domain_assembly_open(domain, "foo.exe");
MonoImage *image = mono_assembly_get_image(assembly);

mono_jit_exec(domain, assembly, argc, argv);

MonoClass *klass = mono_class_from_name(image, "foo", "MainClass");
MonoObject *instance = mono_object_new(domain, klass)

MonoString *string = mono_string_new(domain, "hello");
void *params[] = { string };

//NonGenericStatic call (works)
MonoMethod *method = mono_class_get_method_from_name(klass, "NonGenericStatic", 1);
mono_runtime_invoke(method, NULL, params, NULL);

//NonGenericMember call (works);
method = mono_class_get_method_from(klass, "NonGenericMember", 1);
mono_runtime_invoke(method, instance, params, NULL);

//GenericStatic call (fails)
method = mono_class_get_method_from_name(klass, "GenericStatic", 1);
mono_runtime_invoke(method, NULL, params, NULL);

//GenericMember call (fails)
method = mono_class_get_method_from_name(klass, "GenericMember", 1);
mono_runtime_invoke(method, instance, params, NULL);

mono_jit_cleanup(domain, assembly);

return 0;
}

最佳答案

您不能以这种方式调用通用方法,不幸的是文档有点误导。如果你想调用 public void GenericMember<T>(T t)String参数你必须找到带有签名的方法 public void GenericMember<String>(String t)并使用 mono_runtime_invoke在上面。

更简单的方法是使用 MethodInfo.MakeGenericMethod通过 C# 实用方法的方法:

public static IntPtr Utility(MethodInfo method, Type type)
{
return method.MakeGenericMethod(type).MethodHandle.Value;
}

使用嵌入式 Mono API 找到 Utility方法,用 MonoMethod* 调用它代表GenericMethod<T>(T t)方法和您想要的类型(在您的示例中为 String)。此调用的返回将是 MonoMethod*这将代表 GenericMethod<String>(String t) .这是您需要调用的方法。

我发了一个详细的帖子,里面有源码here .

关于c# - 单声道嵌入,从 C 调用 C# 泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22273150/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com