Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > CallBack или как ее там...


Автор: VinSmile 23.1.2007, 01:29
Доброго всем времени суток!
Я пол часа лазил по поиску но так ничего и не нанашол smile Так что прошу меня туда, и на МСДН (ну не знаю я англиский) не посылать... 
А проблема у меня такая...  Есть длл (моя длл) и есть прога которая ее использует... И вот мне нужно из длл вызвать функцию которая описана в порге которая ее использует. Судя из того что я нашол, тут должны использоваться колбек функции. Но вот только реализация описывалась только со стороны приложения... А как это реализовано в самой длл? Я очень вас прошу написать пару пустых функций демонстрирующих эту взаимосвязь. Тоесть:
1) Что нужно передать в длл.
2) Как правильно описать функцию для вызова из длл.
3) Ну и как именно ее вызвать.
Очень надеюсь на вашу помощь!!!

Автор: casey 23.1.2007, 10:00
Да, тут надо использовать callbackи, но ты должен иметь ввиду, что данная длл-ка может использоваться только одним процессом.

Я когда-то это писал, поэтому вырежу пример из готовой проги:

*.exe  :
Код

typedef void (*CallbackDataChange)(LPCTSTR name,  FILETIME &ftime, VARIANT &val);
extern "C"  __declspec(dllimport) void __stdcall SetCallbacks(CallbackDataChange DataChng);

- это нужно для передачи адреса каллбэк-функции в длл
2) 
Код

void DataChange(LPCTSTR name,  FILETIME &ftime, VARIANT &val)
    {
    ...
    }

сама каллбэк ф-ция

3) Перед вызовом каллбэка из длл нужно передать ее адрес
Код

SetCallbacks(DataChange); 


*.dll
1)
Код

typedef void (*CallbackDataChange)(LPCTSTR name, FILETIME &ftime, VARIANT &val);
CallbackDataChange DataChange;

- объявления
2)
Код

extern "C"  __declspec(dllexport) void __stdcall SetCallbacks(CallbackDataChange DataChng)
{
DataChange=DataChng;
}

- получение и сохранение адреса для последующего вызова

3)
Код

(*DataChange)(name, time, value);

- сам вызов делается так

Может чего забыл, не получится - пиши

Автор: VinSmile 23.1.2007, 21:35
Огромнейшее спасибо!!! Суть полностью уловил!!!  Поставил бы плюс в репу, но прав нехватает smile Думаю админы это оценят... Коротко и ясно... Чтобы все так отвечали... Ещо раз спасибо!!!

Автор: VinSmile 14.2.2007, 19:09
И опять я возвращаюсь к этой теме smile Функция нормально вызываеться пока мое окно в фокусе, то только оно его теряет, как все перестает работать smile
Вот код моего приложения:

DLL
Код

//---------------------------------------------------------------------------

#include <windows.h>
#pragma argsused
#include "KeySpy.h"
//---------------------------------------------------------------------------
CallbackProc HookKeyProc = 0;
//---------------------------------------------------------------------------
HHOOK HKey;
HINSTANCE hInstance;

//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    hInstance = hinst;
    (((reason == DLL_THREAD_DETACH) || (reason == DLL_PROCESS_DETACH)) && !HKey)
        UnhookWindowsHookEx(HKey);
    return 1;
}
//---------------------------------------------------------------------------
int __stdcall KeySpy(int code, int wParam, int lParam){
    if (code >= 0){
        MessageBox(0,"test_dll","test",MB_OK | MB_ICONEXCLAMATION);
        (*HookKeyProc)(code,wParam,lParam);
        return 0;
    }
    return CallNextHookEx(HKey,code,wParam,lParam);
}
//---------------------------------------------------------------------------
void __stdcall setHook(CallbackProc lpHookProc){
    HookKeyProc = lpHookProc;
    HKey = SetWindowsHookEx(WH_KEYBOARD,(WNDENUMPROC)KeySpy,hInstance,0);
}
//---------------------------------------------------------------------------
void __stdcall UnhookHook(){
    UnhookWindowsHookEx(HKey);
    HKey = 0;
}


CPP
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "KeySpy.h"
#include "UTest1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
void KeyHook(int code, int wParam, int lParam){
    MessageBox(0,"Test_CallBack","Шпион мля :)",MB_OK | MB_ICONEXCLAMATION);
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
    if (Button == mbLeft)setHook(KeyHook);
}


"H" (подключен и там и там)
Код

#ifndef _KEYSPY_H
#define _KEYSPY_H

#ifdef __DLL__
#define DLL_EI __declspec(dllexport)
#else
#define DLL_EI __declspec(dllimport)
#endif

typedef void (*CallbackProc)(int code, int wParam, int lParam);

extern "C" void __stdcall DLL_EI  setHook(CallbackProc);
extern "C" void __stdcall DLL_EI  UnhookHook();

#endif


когда коментю строку (*HookKeyProc)(code,wParam,lParam); все работает отлично, хук ставиться и при любом нажатии/отпускании клавиши (для любого окна) весело выскакивает меседжбокс, но вот только стоит ее вернуть на место..... Для окна срабатывает, а потеряю его с фокуса, раз сработает, я закрываю меседжбокс, и все, даже при востановлении фокуса ничего не работает... Вот так smile

Автор: dumb 15.2.2007, 04:26
Цитата(VinSmile @  14.2.2007,  19:09 Найти цитируемый пост)
даже при востановлении фокуса ничего не работает... 

и не будет. callback имеет смысл только в пределах адресного пространства твоей программы. а SetWindowsHookEx подгружает твою dll во все(почти) процессы - в их адресных пространствах адрес твоей функции ничего не значит.
в данном случае для общения dll с основной программой нужно воспользоваться каким-либо IPC. например -  сообщениями, разделяемыми секциями...

ps. фпоиск по "SetWindowsHookEx WH_KEYBOARD".

Автор: VinSmile 15.2.2007, 13:47
Цитата(dumb @  15.2.2007,  04:26 Найти цитируемый пост)
в данном случае для общения dll с основной программой нужно воспользоваться каким-либо IPC. например -  сообщениями, разделяемыми секциями...

А можно поконкретней, что за технология, названия функций, чтобы я знал что искать smile А за ответ спасибо!
P.S. "например -  сообщениями" - Имееться в виду чтото наподобии PostMassage ?

Автор: dumb 15.2.2007, 16:32
IPC = Interprocess Communications

Цитата(VinSmile @  15.2.2007,  13:47 Найти цитируемый пост)
чтото наподобии PostMassage

да. SendMessage/PostMessage

разделяемые секции(MMF-memory mapped files): CreateFileMapping, MapViewOfFile, OpenFileMapping

Автор: VinSmile 15.2.2007, 21:42
Ок... Спасибо! Буду смотреть smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)