1 Востаннє редагувалося Fox (02.01.2018 22:50:37)

Тема: Бiблiотека Mono i трабл з нею.

Маю я програму яка написана на С++ але там я юзаю ще бiблiотеку на С# i mono для того щоб одне з другим працювало.
От в чому трабл.
Написав функцiю для виклику функцiй з С# (вибачаюся за тофтологiю).
Ну все було добре поки я не викликав функцiю C# з двома числовими аргументами.
I виявилося що перший аргумент = другому.
Тобто викликаю так що перший параметр мав бути 3 а другий 5 але вони обидва рiвнi 5.
Може тут пiдкажуть що робити.

Функцiя з С#
public void Name(int param0, int param1, int param2, string param3, string param4, string param5)
    {
        
    }
MonoObject* CallScript(const char* name, char* pdescription, ...)
{
    va_list args;
    int num = strlen(pdescription);
    va_start(args, pdescription);
    std::vector<void*> arg;
    int a = 0;
    char* chars = { 0 };
    for (int i = 0; i < num; i++)
    {
        switch (pdescription[i])
        {
            case 'i':
                a = va_arg(args, int);
                arg.push_back(&a);
                printf("DB: %i\n", a);
                break;
            case 's':
                chars = va_arg(args, char*);
                arg.push_back(mono_string_new_len(mono_domain_get(), chars, (int)strlen(chars)));
                break;
            default:
                break;
        }

    }
    printf("\n\n\n"); 
    void** argscall = &arg[0];
    MonoImage* img = mono_assembly_get_image(mono_domain_assembly_open(mono_domain_get(), "UnityEngine"));
    MonoClass* m_class = mono_class_from_name(img, "UnityEngine", "GameObject");
    MonoMethod* Find = findMethod(m_class, "Find");
    void *object_name[] = { mono_string_new_len(mono_domain_get(), "Inst", (int)strlen("Inst")) };
    MonoObject* Inst= mono_runtime_invoke(Find, nullptr, object_name, nullptr);

    static const char *names[] = { "System.String" };
    MonoString* Name = mono_string_new_len(mono_domain_get(), "Net", (int)strlen("Net"));
    MonoMethod* GetComponent = findMethod(m_class, "GetComponent", 1, names);
    void *args1[] = { Name };
    MonoObject* RK = mono_runtime_invoke(GetComponent, Inst, args1, NULL);
    if (!RK) return NULL;
    MonoImage* img_asm = mono_assembly_get_image(mono_domain_assembly_open(mono_domain_get(), "Assembly-CSharp"));
    MonoClass* rak_class = mono_class_from_name(img_asm, "", "Net");
    MonoMethod* CallMethod = findMethod(rak_class, name);
    if (!CallMethod) { printf("ERR 03\n"); return NULL; }


    return mono_runtime_invoke(CallMethod, Inst, argscall, nullptr);
}


MonoMethod* findMethod(MonoClass* mclass, const char *name, int num_args, const char **arg_typenames)
{
    if (arg_typenames != nullptr) {
        for (MonoClass* mc = mclass; mc; mc = mono_class_get_parent(mclass)) {
            MonoMethod *method;
            gpointer iter = nullptr;
            while ((method = mono_class_get_methods(mclass, &iter))) {
                if (strcmp(mono_method_get_name(method), name) != 0) { continue; }
                MonoMethodSignature *sig = mono_method_signature(method);
                if (mono_signature_get_param_count(sig) != num_args) { continue; }
                MonoType *mt = nullptr;
                gpointer iter = nullptr;
                for (int ia = 0; ia < num_args; ++ia) {
                    mt = mono_signature_get_params(sig, &iter);
                    if (strcmp(mono_type_get_name(mt), arg_typenames[ia]) != 0) {
                        goto next_method;
                    }
                }
                return method;
            next_method:;
            }
        }
    }
    else {
        for (MonoClass* mc = mclass; mc; mc = mono_class_get_parent(mclass)) {
            if (MonoMethod *ret = mono_class_get_method_from_name(mc, name, num_args)) {
                return ret;
            }
        }
    }
    return nullptr;
}

Сам виклик

CallScript("Name", "iissss", ну i тут параметри через кому)

2

Re: Бiблiотека Mono i трабл з нею.

vtorgashov написав:
public void Name(int param0, int param1, int param2, string param3, string param4, string param5)
CallScript("Name", "iissss", ну i тут параметри через кому)

Збільшуємо:

(int , int , int , string , string , string )
"i      i    s        s      s       s"

Щось тут не те.

Подякували: Yola1

3 Востаннє редагувалося Fox (03.01.2018 14:55:51)

Re: Бiблiотека Mono i трабл з нею.

koala написав:
vtorgashov написав:
public void Name(int param0, int param1, int param2, string param3, string param4, string param5)
CallScript("Name", "iissss", ну i тут параметри через кому)

Збільшуємо:

(int , int , int , string , string , string )
"i      i    s        s      s       s"

Щось тут не те.

Та в мене все так...
Це я тут коли писав то помилився
Я вже якось помилився в кодi)
I памятаю що буде краш.

I ца зараза передасть хоть 10 строкових параметрiв i все буде добре.
А 2 числових i усе :С

----------------------------------------------------------------------------------------------
Я зрозумiв чому...
Я в вектор записую силку на змiнну.
I тому останнi записанi даннi воно суне у 2 змiннi.

int p = 1;
    int b = 5;
    void* argscall[] = { &p, &b };

Ось так все коректно...

А от як виправити я не знаю.
Бо йому треба саме силку.
Просто записати arg.push_back((void*)5); = error :C
-----------------------------------------------------------------------------------------------

case 'i':
                a[index] = va_arg(args, int);
                arg.push_back(&a[index]);
                index++;

Ну зробив з а масив на 20 комiрок.
Сподiваюся не знадобиться передавати бiльше int змiнних

4

Re: Бiблiотека Mono i трабл з нею.

Взагалі у вас тут такий жорсткий мікс з C і C++, що навіть і не знаю, радити його розгрібати чи ні. Та ще й з goto.
Найбільший жах, як на мене, тут у findMethod - ви б хоч у якийсь map ті функції збирали, чи що, бо другий виклик буде обчислюватися стільки ж, а там пошук по рядках.

Подякували: ostap34PHP1

5 Востаннє редагувалося Fox (03.01.2018 15:10:01)

Re: Бiблiотека Mono i трабл з нею.

koala написав:

Взагалі у вас тут такий жорсткий мікс з C і C++, що навіть і не знаю, радити його розгрібати чи ні. Та ще й з goto.
Найбільший жах, як на мене, тут у findMethod - ви б хоч у якийсь map ті функції збирали, чи що, бо другий виклик буде обчислюватися стільки ж, а там пошук по рядках.

Ахахахах... То я не такий то гавнокодер)
Я той метод взяв з гiту а CallScript сам писав
"ви б хоч у якийсь map ті функції збирали" Хм... Дякую за iдею

Подякували: ostap34PHP1