LINUX.ORG.RU

Вызов управляемого метода .NET из неуправляемого

 


0

1

Пытаюсь вызвать управляемый метод .NET (C#) из неуправляемого (C++). Делаю по этой и этой инструкциям.

Управляемая библиотека:

namespace TestLib
{
    public static class Class1
    {


        public static int Method1(System.IntPtr arg, int argLength)
        {
            return 1;
        }

        public static int Method1(int a)
        {
            return 2;
        }

    }
}

Вызов методов:

const char_t* type_name = L"TestLib.Class1, TestLib";
const char_t* method_name = L"Method1";
//
component_entry_point_fn method1_cep = nullptr;
std::cout << "Get  Method1(IntPtr, int): " << load_assembly_and_get_function_pointer_fptr(
    dotnetlib_path,
    type_name,
    method_name,
    nullptr,
    nullptr,
    (void**)&method1_cep
) << std::endl;
//
std::cout << "Call Method1(IntPtr, int): " << method1_cep(nullptr, 0) << std::endl;
//
method1_fn method1_int = nullptr;
std::cout << "Get  Method1(int): " << load_assembly_and_get_function_pointer_fptr(
    dotnetlib_path,
    type_name,
    method_name,
    L"Method1(int)",
    nullptr,
    (void**)&method1_int
) << std::endl;
//
std::cout << "Call Method1(int) : " << method1_int(2) << std::endl;

Вывод:

Get  Method1(IntPtr, int): 0
Call Method1(IntPtr, int): 1
Get  Method1(int): -2146233054
Exception

Т.е. получение и вызов метода Method1(System.IntPtr arg, int argLength) (без указания сигнатуры) проходит успешно. Я же хочу вызывать методы с указанием сигнатуры, но по какой-то причине hostfxr не может найти метод Method1(int).

В чём может быть проблема?

Из документации

  • method_name - Name of the method on the type_name to find. The method must be static and must match the signature of delegate_type_name.
  • delegate_type_name - Assembly qualified delegate type name for the method signature
★★

Почему не попробовать c++/cli вместо чистых плюсов? Там и маршаллинг есть

anonymous ()
Ответ на: комментарий от anonymous

Я вызываю из внешней системы, которая умеет дёргать методы dll. Пример/тестовая программа на C++ для упрощения тестирования и проверки корректности.

SaBo ★★ ()

Почему не работает load_assembly_and_get_function_pointer разобрался: в delegate_type_name нужно указывать не сигнатуру метода, а подходящий под сигнатуру делегат.

namespace TestLib
{
    public static class Class1
    {


        public static int Method1(System.IntPtr arg, int argLength)
        {
            return 1;
        }

        public static int Method1(int a)
        {
            return a * 2;
        }

        public delegate int Method1Delegate(int a);

    }
}
typedef int (*method1_fn)(int);

...

method1_fn method1_int = nullptr;
std::cout << "Get  Method1(int): " << load_assembly_and_get_function_pointer_fptr(
    dotnetlib_path,
    type_name,
    method_name,
    L"TestLib.Class1+Method1Delegate, TestLib",
    nullptr,
    (void**)&method1_int
) << std::endl;

Правда, теперь приложение вылетает при попытке вызова метода:

int a = 3;
std::cout << "Call Method1(int) : " << method1_int(a) << std::endl;

SaBo ★★ ()
Последнее исправление: SaBo (всего исправлений: 1)
Ответ на: комментарий от SaBo

Разобрался. Неправильно указан method1_fn, нужно так:

typedef int (CORECLR_DELEGATE_CALLTYPE*method1_fn)(int32_t);
SaBo ★★ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.