C3374: невозможно получить адрес функции, если не создан экземпляр делегата

У меня возникли проблемы с использованием функции регистрации сторонней библиотеки для регистрации обратного вызова. Я пишу в C++ CLI и обращаюсь к библиотеке, написанной на C или C++.

Что означает вышеуказанная ошибка компилятора?

это функция регистрации, как определено продавцом:

MYCO int WINAPI MyCo_Device_Register_CallbackFunc(LPVOID func, LPVOID lpParam, DWORD mask);

это обратный вызов, как определено поставщиком:

typedef void (CALLBACK* MyCo_Device_CallbackProc)(DWORD ddStatus, LPVOID lpParam);

Моя функция обратного вызова:

public ref class Device 
{
    void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

Мой звонок (который терпит неудачу):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF);

2 ответа

Решение

Если бы мне пришлось отыграть предположение, вы пытаетесь взять адрес функции MANAGED и передать ее как указатель на функцию NATIVE. Это не сработает вообще. Либо напишите собственный мост (сложнее и, вероятно, без преимущества), либо (и это более простой подход) создайте делегата и используйте Marshal.GetFunctionPointerForDelegate. Не забывайте, что делегат должен оставаться в живых до тех пор, пока нативный код ожидает перезвонить, поэтому вам, скорее всего, нужно его где-то хранить.

Да, и все функции внутри класса ref или класса значений являются управляемыми функциями, в случае, если это неясно.

[РЕДАКТИРОВАТЬ] Расширение ответа, чтобы покрыть вопросы в комментариях. Первым шагом является создание соответствующего делегата. Для предоставленной вами функции она будет выглядеть так:

public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam);

Затем вам нужно создать один:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);

И, как отмечалось ранее, вы должны хранить этот IN в своем классе в качестве члена, чтобы убедиться, что он не исчезает. Наконец, вам нужно получить указатель на функцию и передать его:

MyCo_Device_Register_CallbackFunc((MyCo_Device_CallbackProc) Marshal::GetFunctionPointerForDelegate(del).ToPointer(), 0, 0);

Я думаю, что это охватывает все. Все, что вам нужно, это использовать систему имен пространства; и ты должен быть в порядке.

Ваша функция обратного вызова - член - указатель на член и указатель на функции - это разные вещи.

Даже в решении Promit:

CallbackFuncDelegate(CallbackFunc)

CallbackFunc не должен быть членом класса

Вы можете написать просто

public ref class Device 
{
    static void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

а затем использовать

Device::CallBackFunc
Другие вопросы по тегам