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);
해결책
내가 추측을 베팅해야한다면, 당신은 관리 된 기능의 주소를 가져 와서 기본 기능 포인터로 전달하려고합니다. 그것은 전혀 작동하지 않을 것입니다. 네이티브 브리지 (더 단단하고 아마도 이점이 없음)를 쓰거나 (그리고 이것은 더 쉬운 접근법) 대의원을 만들고 사용합니다. Marshal.getFunctionPointerfordElegate. 대의원은 기본 코드가 다시 호출 할 것으로 예상되는 기간 동안 살아 있어야한다는 것을 잊지 마십시오.
오, 그리고 Ref 클래스 또는 값 클래스 내의 모든 기능은 명확하지 않은 경우 관리 기능입니다.
편집] 의견에 대한 질문에 대한 답변 확장. 첫 번째 단계는 일치하는 대의원을 만드는 것입니다. 제공 한 기능의 경우 다음과 같습니다.
public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam);
그런 다음 하나를 만들어야합니다.
CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);
그리고 앞에서 언급했듯이, 당신은 그것이 사라지지 않도록하기 위해 수업에서 회원으로 저장해야합니다. 마지막으로 기능 포인터를 가져 와서 전달해야합니다.
MyCo_Device_Register_CallbackFunc((MyCo_Device_CallbackProc) Marshal::GetFunctionPointerForDelegate(del).ToPointer(), 0, 0);
나는 그것이 모든 것을 다루고 있다고 생각합니다. 네임 스페이스 시스템을 사용하기 만하면됩니다. 그리고 당신은 괜찮을 것입니다.
다른 팁
콜백 func는 멤버입니다. 멤버에 대한 포인터 및 기능에 대한 포인터는 다른 것입니다.
Promit의 해결책에서도 :
CallbackFuncDelegate(CallbackFunc)
CallbackFunc은 클래스 멤버가되어서는 안됩니다
당신은 간단히 쓸 수 있습니다
public ref class Device
{
static void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}
그리고 사용하십시오
Device::CallBackFunc