C3374: não pode tomar o endereço de 'função', a menos que a criação de instância de delegado

StackOverflow https://stackoverflow.com/questions/822582

  •  03-07-2019
  •  | 
  •  

Pergunta

Estou tendo dificuldade em usar uma função de registro de biblioteca thirdparty para registrar um callback. Estou escrevendo em C ++ CLI, e acessar uma biblioteca escrita em C ou C ++.

O que a média erro do compilador acima?

Esta é a função de registro conforme definido pelo fornecedor:

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

Este é o retorno de chamada, conforme definido pelo fornecedor:

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

A minha função de retorno:

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

Meu chamado (que não):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF);
Foi útil?

Solução

Se eu tivesse que apostar um palpite, você está tentando tomar o endereço de uma função gerenciada e passá-lo como um ponteiro de função nativa. Isso não vai funcionar em tudo. Ou escrever uma ponte nativa (mais difícil e provavelmente nenhuma vantagem), ou (e esta é a abordagem mais fácil), crie um delegado e uso Marshal.GetFunctionPointerForDelegate . Não se esqueça que o delegado tem de permanecer vivo para a duração que os espera código nativo para chamar de volta, então você provavelmente necessidade de armazená-lo em algum lugar.

funções Oh, e todas as funções dentro de uma classe ref ou classe de valor são geridos, no caso de que não estava claro.

[EDIT] Expansão resposta às perguntas de cobertura nos comentários. O primeiro passo é criar um delegado correspondente. Para a função que você forneceu, ele vai ficar assim:

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

Em seguida, você precisa criar um:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);

E, como observado anteriormente, você deve armazenar que em sua classe como um membro, a fim de se certificar de que não desaparece. Por último, você precisa para obter o ponteiro de função e passá-lo para baixo:

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

Eu penso que cobre tudo. Tudo que você precisa é using namespace System; e você deve ser fino.

Outras dicas

seu func callback é membro -. Ponteiro para membros e ponteiros para funções são coisas diferentes

Mesmo em solução de Promit:

CallbackFuncDelegate(CallbackFunc)

CallbackFunc não deve ser membro da classe

Você pode escrever simplesmente

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

e, em seguida, usar

Device::CallBackFunc
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top