Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Lucas
Зарегистрирован: 25.02.2003 Сообщения: 6
|
Добавлено: Вт Фев 25 2003 07:54 Заголовок сообщения: Обьен данными с DLL |
|
|
ПРЕЛЮДИЯ: В программе 2 потока. Второй поток вызывает функцию из DLL:
... (*fpDraw)(x,y); //вызываем функцию Draw из DLL ...
fpDraw описывается следующим образом: typedef void WINAPI (DrawFunc)(int &,int&); DrawFunc *fpDraw;
Функция Draw из DLL меняет значения переданных в нее переменных (они передаются как ссылки). Ее заголовок: extern "C" __declspec(dllexport) void WINAPI Draw(int &, int &);
Переменные x,y - глобальные переменные: extern int x,y;
В первом потоке есть функция, которая рисует на экране точку с координатами x,y.
Причем вся эта хрень делается с помощью синхронизации потоков (т.е. первый поток отлавливает момент, когда DLL меняет координаты)
ПРОБЛЕМА: При попытке присвоить переменным, переданным с помощью ссылки, какое-либо значение в теле DLL-функции Draw выскакивает синий экран, на котором написано что-то типа: "Программа вызвала сбой по адресу ... Приложение будет закрыто"
У кого-нибудь есть какие-нибудь предположения? |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Вт Фев 25 2003 10:18 Заголовок сообщения: Re: Обьен данными с DLL |
|
|
Ну судя по всему, синхронизация потоков там плохо реализована. |
|
Вернуться к началу |
|
|
Lucas
Зарегистрирован: 25.02.2003 Сообщения: 6
|
Добавлено: Ср Фев 26 2003 13:56 Заголовок сообщения: Re: Обьен данными с DLL |
|
|
Синхронизация потоков тут ни причем (в смысле причина не в этом). Даже если оставить один поток, который вызывает функцию DLL (передавая в нее адреса 2-ух глобальных переменных типа int как ссылки), то при попытке присвоить этим переменным какие-нибудь значения в теле этой DLL-евской функции происходит мать его непонятный ни чем необъяснимый гребаный ГЛЮК, материализующийся в виде синего экрана с указанной в первом сообщении надписью. |
|
Вернуться к началу |
|
|
Adil Гость
|
Добавлено: Ср Фев 26 2003 14:05 Заголовок сообщения: Re: Обьен данными с DLL |
|
|
Ну тогда кусок кода в студию... |
|
Вернуться к началу |
|
|
Lucas
Зарегистрирован: 25.02.2003 Сообщения: 6
|
Добавлено: Ср Фев 26 2003 14:44 Заголовок сообщения: Re: Обьен данными с DLL |
|
|
Сейчас под рукой его нету , но завтра обязательно. Вообще тема сия весьма любопытна. Тока-што один очень уважаемый человек выдал такую гипотезу: типа каждая загруженная DLL имеет свое адресное пространство (в целях безопасности) , и что работать с указателями в данном случае нельзя, нужно работать с идентификаторами(процессов, DLL) - я пока в легком трансе перерабатываю, что он сказал. |
|
Вернуться к началу |
|
|
Lucas
Зарегистрирован: 25.02.2003 Сообщения: 6
|
Добавлено: Чт Фев 27 2003 15:19 Заголовок сообщения: кусок кода в студии |
|
|
Поток #1:
#include #pragma hdrstop
#include "Unit1.h" #include "Unit2.h" #include "Unit4.h" #pragma package(smart_init)
extern HANDLE hEvent; bool ProgramThread2IsAlive; extern int x,y; HDC hdc;
TDLLThread *DLLThread;
//------------------------------------------- -__fastcall TProgramThread2::TProgramThread2(bool CreateSuspended) : TThread(CreateSuspended) { }
//------------------------ --------------------void __fastcall TProgramThread2::Execute() { //этот поток выполняется с приоритетом TimeCritical
//булевская переменная, True - первый поток жив, False - мертв ProgramThreadIsAlive=True;
//свойство класса TThread, чтобы занятая потоком память освобождалась при завершении потока FreeOnTerminate=True;
//Создаем событие hEvent=CreateEvent(NULL,False,True,NULL);
//создаем экземпляр класса TThread в приостановленном виде DLLThread=new TDLLThread(True);
//если нужно, производим какую-нить инициализацию
//запускаем второй поток DLLThread->Resume();
//булевская переменная, True - второй поток жив, False - мертв DLLThreadIsAlive=True; x=0; y=0;
while (DLLThreadIsAlive && ProgramThreadIsAlive) { WaitForSingleObject(hEvent,INFINITE); DrawPoint(); SetEvent(hEvent); } if (!ProgramThreadIsAlive) TerminateThread((HANDLE)DLLThread->Handle, false); else ProgramThreadIsAlive=False; if (DLLThreadIsAlive) DLLThreadIsAlive=False; CloseHandle(hEvent); } //------------------------------- ------------- void __fastcall TProgramThread2::DrawPoint() { hdc=GetDC(handle); LineTo( hdc,x,y); ReleaseDC(handle,hdc); //handle описан и инициализирован в др. модуле как внешняя переменная }
Поток #2:
#pragma hdrstop #include "Unit1.h" #include "Unit2.h" #include "Unit4.h" #pragma package(smart_init)
bool DLLThreadIsAlive; HANDLE hEvent,hDLL; int x,y;
typedef void WINAPI (DrawFunc)(HANDLE,int &,int &); DrawFunc *fpDraw; //------------------------------------------------ ---------------------------
__fastcall TDLLThread::TDLLThread(bool CreateSuspended) : TThread(CreateSuspended) { } //-------------------------- ------------------------------------------------- void __fastcall TDLLThread::Execute() { FreeOnTerminate=True; hDLL=LoadLi brary(""); if (fpDraw=(DrawFunc*)::GetProcAddress(hDLL,"Draw")) { (*fpDraw)(hEvent,x,y); } DLLThreadIsAlive=False; }
Код DLL:
#include #pragma hdrstop
int i; extern "C" __declspec(dllexport) void WINAPI Draw(HANDLE,int &,int &); void GRAF2(int &,int &); //----------------------------------------------------- ------------------------ extern "C" __declspec(dllexport) void WINAPI DrawGraph(HANDLE hEvent,int &x,int &y) { WaitForSingleObject(Event,INFINITE); GRAF2(x,y); S etEvent(Event); } //-------------------------------------- ---------------------------------------- void GRAF2(int &x,int &y) { x=10; y=10; } // ... |
|
Вернуться к началу |
|
|
|