Рейтинг:
17
Jochen Arndt
Он является общим, чтобы использовать typedef
для таких функций, потому что это облегчает объявление указателей.
Для вашего случая см. Указатель функции PWINBIO_CAPTURE_CALLBACK (Windows)[^]:
typedef VOID ( CALLBACK *PWINBIO_CAPTURE_CALLBACK)(
_In_opt_ PVOID CaptureCallbackContext,
_In_ HRESULT OperationStatus,
_In_ WINBIO_UNIT_ID UnitId,
_In_ PWINBIO_BIR Sample,
_In_ SIZE_T SampleSize,
_In_ WINBIO_REJECT_DETAIL RejectDetail
);
Затем объявите переменную как
PWINBIO_CAPTURE_CALLBACK pCaptureCallback;
[РЕДАКТИРОВАТЬ]
Я не был уверен как
CALLBACK
решается. Но кажется, что он не содержит
static
Поскольку функции обратного вызова должны быть статическими, объявление в качестве функции-члена класса должно быть
/* CBioMetricApplicationDlg.h */
static VOID CALLBACK CaptureCallback(
__in_opt PVOID CaptureCallbackContext,
__in HRESULT OperationStatus,
__in WINBIO_UNIT_ID UnitId,
__in_bcount(SampleSize) PWINBIO_BIR Sample,
__in SIZE_T SampleSize,
__in WINBIO_REJECT_DETAIL RejectDetail
);
Чтобы получить доступ к классу внутри функции обратного вызова пройдите
this
как параметр контекста:
/* CBioMetricApplicationDlg.cpp */
hr = WinBioCaptureSampleWithCallback(
sessionHandle,
WINBIO_NO_PURPOSE_AVAILABLE,
WINBIO_DATA_FLAG_RAW,
CaptureSampleCallback,
this);
и приведите параметр в функцию обратного вызова:
/* CBioMetricApplicationDlg.cpp */
VOID CBioMetricApplicationDlg::CaptureCallback(
__in_opt PVOID CaptureCallbackContext,
__in HRESULT OperationStatus,
__in WINBIO_UNIT_ID UnitId,
__in_bcount(SampleSize) PWINBIO_BIR Sample,
__in SIZE_T SampleSize,
__in WINBIO_REJECT_DETAIL RejectDetail
)
{
CBioMetricApplicationDlg *pThis = reinterpret_cast<CBioMetricApplicationDlg*>(CaptureCallbackContext);
// Use pThis to access class members
// ...
}
[/РЕДАКТИРОВАТЬ]
Premnath Mali
получение этой ошибки при инициализации
pCaptureCallback = &CBioMetricApplicationDlg:: CaptureCallback;
Jochen Arndt
Все та же ошибка?
Я не могу проверить это здесь в данный момент.
Вы можете попробовать упростить typedef:
typedef VOID (*PWINBIO_CAPTURE_CALLBACK)(
PVOID CaptureCallbackContext,
HRESULT OperationStatus,
WINBIO_UNIT_ID UnitId,
PWINBIO_BIR Sample,
SIZE_T SampleSize,
WINBIO_REJECT_DETAIL RejectDetail
);
Это предполагает, что обратный вызов разрешает что-то содержащее
static
.
Если нет, то вы должны объявить функцию как статическую в вашем заголовочном файле:
static VOID CALLBACK CaptureCallback(
// ...
Premnath Mali
//in header file
VOID CALLBACK CaptureCallback(
__in_opt PVOID CaptureCallbackContext,
__in HRESULT OperationStatus,
__in WINBIO_UNIT_ID UnitId,
__in_bcount(SampleSize) PWINBIO_BIR Sample,
__in SIZE_T SampleSize,
__in WINBIO_REJECT_DETAIL RejectDetail
);
typedef VOID ( CALLBACK *PWINBIO_CAPTURE_CALLBACK)(
_In_opt_ PVOID CaptureCallbackContext,
_In_ HRESULT OperationStatus,
_In_ WINBIO_UNIT_ID UnitId,
_In_ PWINBIO_BIR Sample,
_In_ SIZE_T SampleSize,
_In_ WINBIO_REJECT_DETAIL RejectDetail
);
PWINBIO_CAPTURE_CALLBACK pCaptureCallback;
//in onInitDialog()
pCaptureCallback = &CBioMetricApplicationDlg::CaptureCallback;
//in Cpp file Defination of callback method
VOID CALLBACK CBioMetricApplicationDlg::CaptureCallback(PVOID CaptureCallbackContext,
HRESULT OperationStatus,
WINBIO_UNIT_ID UnitId,
PWINBIO_BIR Sample,
SIZE_T SampleSize,
WINBIO_REJECT_DETAIL RejectDetail)
{
//defination
}
и ошибка есть...
ошибка C2440:'=': не удается преобразовать из 'void (__stdcall CBioMetricApplicationDlg::* ) (PVOID, HRESULT, WINBIO_UNIT_ID,PWINBIO_BIR, SIZE_T, WINBIO_REJECT_DETAIL)' в 'CBioMetricApplicationDlg:: PWINBIO_CAPTURE_CALLBACK'
Jochen Arndt
Таким образом, обратный вызов не содержит статики (используйте символ follow в контекстном меню)?
Затем вы должны объявить функцию обратного вызова как статическую в заголовочном файле (2-й вариант из моего предыдущего комментария).
Premnath Mali
Также Эта ошибка, которую я получаю
ошибка C2724: 'CBioMetricApplicationDlg:: CaptureCallback' : 'static' не следует использовать для функций-членов, определенных в области действия файла
Premnath Mali
если я использую статический метод обратного вызова, то я не смогу получить доступ к другому члену класса...
Jochen Arndt
Функция обратного вызова ДОЛЖЕН будьте статичны.
Они обычно предоставляют параметр, который можно использовать для передачи указателя на класс.
В вашем случае это CaptureCallbackContext<code> parameter. Call <code>WinBioCaptureSampleWithCallback(this, ...)
и приведите параметр в функцию обратного вызова:
CBioMetricApplicationDlg *pThis = (CBioMetricApplicationDlg*)CaptureCallbackContext;
Premnath Mali
хорошо я объявляю этот метод статическим но как я могу дать определение
если я отдам вот так
static VOID CALLBACK CBioMetricApplicationDlg::CaptureCallback(PVOID CaptureCallbackContext,
HRESULT OperationStatus,
WINBIO_UNIT_ID UnitId,
PWINBIO_BIR Sample,
SIZE_T SampleSize,
WINBIO_REJECT_DETAIL RejectDetail)
{
//defination
}
тогда я получаю эту ошибку
ошибка C2724: 'CBioMetricApplicationDlg:: CaptureCallback' : 'static' не следует использовать для функций-членов, определенных в области действия файла
и если я даю определение без статического ключевого слова, то я получаю следующую ошибку
Ошибка 1 ошибка lnk2001: неразрешенных внешних символ "общественности: статический недействительными __CBioMetricApplicationDlg нарушением соглашения о стандартном::IdentifyCallback(недействительными *,неподписанные долго,долго _WINBIO_IDENTITY структуры *,без знака типа char,беззнаковый Long)" (?IdentifyCallback@CBioMetricApplicationDlg@@SGXPAXJKPAU_WINBIO_IDENTITY@@ВК@з) BioMetricApplicationDlg. obj
Jochen Arndt
Смотрите мой обновленный ответ.
Ключевое слово static должно использоваться для объявления в заголовочном файле, но не для определения функции в исходном файле.
Premnath Mali
Спасибо!
Теперь это работает
Jochen Arndt
Прекрасно слышать это и благодарить вас за обратную связь и принятие моего решения.
Но я должен был заметить раньше, что ваш функтон не был статичным (__thiscall из первоначального сообщения об ошибке-это подсказка).
Premnath Mali
Сэр,
Извините, что снова прерываю вас, но во время использования есть одна маленькая проблема
pThis->ShowMessage(_T("Message"));
где ShowMessage-это функция-член
//def of ShowMessage()
void CBioMetricApplicationDlg::ShowMessage(CString msg)
{
CString preMsg = _T("\n::::Keep Looking at Instructions::::\n\n");
m_lblMessage.SetText(preMsg + msg);
}
и ошибка произошла во время выполнения...
Необработанное исключение в 0x003a1d1e in BioMetricApplication.exe: 0xC0000005: нарушение доступа к местоположению чтения 0x000000a0.
Jochen Arndt
Как правило, избегайте вызова функций графического интерфейса MFC из функций обратного вызова. Функции MFC не являются потокобезопасными, и такие функции обратного вызова ввода-вывода обычно вызываются из разных потоков (драйверов устройств).
В зависимости от того, что вы хотите сделать, вы можете использовать общие буферы для данных, общие переменные для статуса или отправлять пользовательские сообщения в свой класс MFC.
Но это нечто иное и на самом деле не имеет отношения к первоначальному вопросу.
Однако ошибка может быть получена и в другом месте (проверьте, является ли pThis / переданный CaptureCallbackContext допустимым указателем на ваш класс).
Premnath Mali
да, это действительный указатель. Приложение останавливается на
m_lblMessage.SetText(preMsg+msg);
но ваше предложение я буду размещать сообщения для классов MFC
благодарим Вас за дополнительную информацию о функциях вызова в mfc.
Еще раз спасибо!