WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  C / C++ / Visual C++
  DLL в Visual C++

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   DLL в Visual C++
gonzales опубликован 20-12-2001 21:35 MSK   Click Here to See the Profile for gonzales   Click Here to Email gonzales  
Помогите кто-нибудь. Я ламер.
Каким образом я могу в DLL сделать глобальную переменную , которую смогу использовать в главном приложении?
Я делаю всё как написано в Example но и пишу всякие extern "C" но у меня получается
"unresolved":((
kourov опубликован 21-12-2001 08:05 MSK     Click Here to See the Profile for kourov  Click Here to Email kourov     
Да, ты действительно ламер, твой путь тупее некуда, но можно сделать то, что тебе нужно:

// В DLL

#pragma data_seg(".shared") // переменная в общем сегменте
#pragma data_seg()
int my_variable;
#pragma comment(linker, "/SECTION:.shared,RWS")

int CALLBACK GetMyVariable()
{
return my_variable;
}

// В приложении вызывай функцию GetMyVariable() из DLL

kourov опубликован 21-12-2001 08:07 MSK     Click Here to See the Profile for kourov  Click Here to Email kourov     
Мля, только int my_variable; надо второй строчкой, после #pragma data_seg(".shared")
gonzales опубликован 21-12-2001 23:27 MSK     Click Here to See the Profile for gonzales  Click Here to Email gonzales     
Спасибо , ты мне здорово помог.
Если можешь, расскажи про более хороший путь или немножко объясни данный example:))
Просто интересно ,почему я не могу создать
dll с функцией , которая будет возвращать
адрес моей глобальной переменной (без всяких там #pragma data_seg(".shared") )?
DmitryRyvkin опубликован 22-12-2001 06:05 MSK     Click Here to See the Profile for DmitryRyvkin  Click Here to Email DmitryRyvkin     
Чего то я тоже непонял, почему он ламер ?
Наверное потому что сам ламер. (точнее чайник)
stan опубликован 22-12-2001 11:33 MSK     Click Here to See the Profile for stan  Click Here to Email stan     
Насколько я помню, у Рихтера было написано так: когда две ДЛЛ грузятся в память, их сегмент данных находится на одних и тех же страницах с атрибутом COPY_ON_WRITE, и если ты попробуешь изменить переменную, то для процесса будет выделена ДРУГАЯ страница, которая замапится на его адресное пространство. Так будет если секция не помечена как shared. Примерно так.
gonzales опубликован 23-12-2001 10:35 MSK     Click Here to See the Profile for gonzales  Click Here to Email gonzales     
Я , недавно наконец-то узнал ,что мне было нужно:)) Я хотел переменные грузить динамически . Я не предполагал , что это можно делать GetProcAddress-ом (меня смутило слово Proc).
kourov опубликован 24-12-2001 08:02 MSK     Click Here to See the Profile for kourov  Click Here to Email kourov     
2 DmitryRyvkin. А что, использование extern "C" для переменной в главном приложении с целью создать глобальную переменную в DLL - это не ламерство?? Вопрос, конечно, не ламерский, но чел изначально выбирал ламерский путь.
Flex Ferrum опубликован 24-12-2001 10:55 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Народ, а помоему человек спрашивал немного о другом.
gonzales:

Попробуй так:

В .h файле пишешь:

#ifdef _DLL
extern __declspec(dllexport) int GlobalVar;
#else
extern __declspec(dllimport) int GlobalVar;
#endif

Потом в каком-нибудь из .cpp файлов определяешь:
int GlobalVar;

По идее, все должно работать. И, кстати, когда создаешь DLL визардом от VisualC он приводит примеры того, как делать экспортируемые переменные и функции.

gonzales опубликован 25-12-2001 16:10 MSK     Click Here to See the Profile for gonzales  Click Here to Email gonzales     
Спасибо , что помогли разобраться.
У меня последнее время вообще куча вопросов по dll. Например у меня не получается
экспортить функции с параметрами и которые
callback . Вообще я сейчас пытаюсь делать хуки . Ещё есть следующая проблема.
Я делаю структурку, потом делаю её экспорт,
но когда смотрю её в теле хука , там везде
0 и "". Если не лень помогите только не надо
кидаться ссылками.
michl_m опубликован 25-12-2001 16:42 MSK     Click Here to See the Profile for michl_m  Click Here to Email michl_m     
Прочти Джеффри Рихтера. Там есть и DLL, и ловушки.
ADK опубликован 25-12-2001 17:02 MSK     Click Here to See the Profile for ADK  Click Here to Email ADK     
Вообще, рекомендую тебе особо не париться.
1) Сделай так, чтобы DLL и EXE компилировались в один каталог (настрой параметры).
2) Надеюсь, ты знаешь, как экспортировать функции DLL. Советую тебе без всяких __declspec писать имена функций в *.DEF файле.
3) Сделай файл типа HOOK.H, который будет содержать общие для EXE и DLL функции и объявления.
4) #include его и к EXE и к DLL.
5) В результате компиляции DLL получается LIB файл, добавь его в список библиотек EXE на вкладке linker, libraries.
6) Если всё путём, то не надо никаких GetProcAddress и т.д, все будет прозрачно.
7) Если ничего не вышло, шли письмо на kourov@newmail.ru, пошлю примерчик хуков, где есть всё, о чём писал.
gonzales опубликован 25-12-2001 22:13 MSK     Click Here to See the Profile for gonzales  Click Here to Email gonzales     
Cкиньте ,кто может ссылочек побольше на эту тему.
ADK опубликован 26-12-2001 05:33 MSK     Click Here to See the Profile for ADK  Click Here to Email ADK     
Ну вот смотри, я писал прогу, суть которой, чтобы в программе PCAD 2000 заработало колесо мыши для масштабирования и центрирования. Перехватываем сообщения от колеса и посылаем клавиатурный эквивалент. Вот код DLL:

#include "..\hook.h"
#include "Shlwapi.h"
#include "correct.h"

#define WM_MOUSEWHEEL 0x020A


#pragma data_seg(".shared") // ðàçìåùàåì ïåðåìåííóþ â îáùåì ñåãìåíòå ïàìÿòè

HWND ghwndSpyHook = NULL; // the handle back to the executable
HHOOK hhkGetMessage = NULL;
BOOL bHookEnabled = TRUE;

#pragma data_seg()

#pragma comment(linker, "/SECTION:.shared,RWS")

LRESULT __fastcall SafePostMessage(
HWND hWnd, // handle of destination window
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
if(IsWindow(hWnd)) return PostMessage(hWnd, Msg, wParam, lParam);
else return 0;
}

void HandleMButtonUp(WPARAM wParam, LPARAM lParam)
{
keybd_event('C', 0, 0, 0 );
keybd_event('C', 0, KEYEVENTF_KEYUP, 0);
}

void HandleMouseWheel(WPARAM wParam, LPARAM lParam)
{
short zDelta = (short) HIWORD(wParam);

if(zDelta < 0)
{
keybd_event(VK_ADD, 0, 0, 0 );
keybd_event(VK_ADD, 0, KEYEVENTF_KEYUP, 0);
}
else
{
keybd_event(VK_SUBTRACT , 0, 0, 0 );
keybd_event(VK_SUBTRACT , 0, KEYEVENTF_KEYUP, 0);
}
}

BOOL ItIsPCAD(HWND hwnd)
{
char szBuf[MAX_PATH];
GetModuleFileName(0, szBuf, sizeof(szBuf));

if(!StrStrI(szBuf, "pcb.exe")) return FALSE;

GetClassName(hwnd, szBuf, sizeof(szBuf));

if(lstrcmp(szBuf, "AfxFrameOrView42s")) return FALSE;

return TRUE;
}

BOOL LCHookProc(
HWND hwnd,
UINT uiMessage,
WPARAM wParam,
LPARAM lParam
)
{
if (ghwndSpyHook)
{
if(ItIsPCAD(hwnd))
{
if(uiMessage == WM_MOUSEWHEEL)
HandleMouseWheel(wParam, lParam);
if(uiMessage == WM_MBUTTONUP)
HandleMButtonUp(wParam, lParam);
}
}

return FALSE;
}

LRESULT CALLBACK
GetMsgProc(
int hc,
WPARAM wParam,
LPARAM lParam
)
{
PMSG pmsg;

pmsg = (PMSG)lParam;

if(bHookEnabled && hc == HC_ACTION && pmsg && pmsg->hwnd && wParam == PM_REMOVE)
{

LCHookProc(pmsg->hwnd, pmsg->message, pmsg->wParam, pmsg->lParam);
}

return CallNextHookEx(hhkGetMessage, hc, wParam, lParam);
}


BOOL CALLBACK SetHook(BOOL fSet, HWND hwndSpy)
{

if (fSet)
{
if (!hhkGetMessage)
{
ghwndSpyHook = hwndSpy;

if (!(hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE,
(HOOKPROC)GetMsgProc, GetModuleHandle("hook.dll"), 0)))
{
return FALSE;
}
}
}
else
{
if (hhkGetMessage)
{
UnhookWindowsHookEx(hhkGetMessage);
hhkGetMessage = NULL;
}
}

return TRUE;
}

BOOL CALLBACK EnableHook(BOOL bEnable)
{
BOOL bEnableStateOld = bHookEnabled;
bHookEnabled = bEnable;
return bEnableStateOld;
}

/// Теперь код HOOK.h

BOOL CALLBACK SetHook(BOOL fSet, HWND hwndSpy);
BOOL CALLBACK EnableHook(BOOL bEnable);

/// Тут даже лишнего много, EnableHook не обязателен.

/// Вот некоторый код для EXE. Обычный EXE (Dialog based).

BOOL CPCADWheelDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog

if(!SetHook(TRUE, GetSafeHwnd()))
{
AfxMessageBox("Îøèáêà óñòàíîâêè ëîâóøêè.", MB_ICONSTOP);
PostMessage(WM_COMMAND, IDCANCEL);
};

AddTrayIcon();

return TRUE; // return TRUE unless you set the focus to a control
}

// Главное HOOK.H включить и в EXE, и в DLL.

ADK опубликован 26-12-2001 05:36 MSK     Click Here to See the Profile for ADK  Click Here to Email ADK     
Погано, что в форуме форматирование кода теряется (отступы). Если будешь переносить в VC++, выдели текст и нажми Alt+F8. Всё будет отформатировано путём!
ADK опубликован 26-12-2001 05:42 MSK     Click Here to See the Profile for ADK  Click Here to Email ADK     
Не забудь подключить lib файл, получающийся при компиляции DLL. В EXE проекте добавь в список библиотек: Project->Settings->(All Configurations)->Link->Object/Library Modules. Допиши свою Lib (у меня hook.lib к примеру).
gonzales опубликован 28-12-2001 15:00 MSK     Click Here to See the Profile for gonzales  Click Here to Email gonzales     
Спасибо . Кстати я ещё попробовал memory-mapped files .C ними, вообщем, тоже всё
работает. Но было бы интересно узнать , как
всё это дело работает.
И ещё , я в data_seg объявляю структурку, но
если я правильно понял , то чтобы в нём
чего-то сделать нужно переменной присвоить начальное значение. Что мне делать?

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.