А где я его буду хранить в dll-ке между вызовами?Shaos wrote:так тебе только адрес передать через файл, а потом все через этот адрес перекидывать

Moderator: Shaos
А где я его буду хранить в dll-ке между вызовами?Shaos wrote:так тебе только адрес передать через файл, а потом все через этот адрес перекидывать
Вот здесь, как мне кажется, излагают эту бадью про "общую область":Lavr wrote:Есть какие-то специальные области памяти для межпотокового общения.
Давно читал я и не понял и забыл...
Честно говоря, опять нифига не понял...Article #20132: How to create a shared segment in a dll.
Question:
How do I build a dll that contains a shared data segment? Books I've been reading mention the #pragma data_seg() directive, but this doesn't seem to be supported by Builder.
Answer:
Builder 4 does not support the #pragma data_seg() directive, but there are compiler switches that will, along with the proper .def file, allow you to do this.
You will have to put the data you want shared in it's own source file and use the -zR and -zT compiler switches. These switches change the data segment name and class name for whatever source file they are used in. You will have to initialize the data you want to share, as uninitialized data is automatically moved to the default data segment. You must also create a .def file for your dll that tells the linker to give that segment the shared property.
Example:
There are four files in this example:
Code: Select all
dll.h // foreward declarations for the dll dllmain.cpp // the CPP file that contains the dll entrypoint dllshared.cpp // contains the shared data dlldef.def // module definition file for the dll #pragma hdrstop #include #define __dll__ #include "dll.h" #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) \{ return 1; \} extern int SharedInteger; int GetInteger(void) \{ return SharedInteger; \} void SetInteger(int arg) \{ SharedInteger = arg; \} //---- end file dllmain.cpp ----// //---- begin file dllshared.cpp ----// #pragma option -zRSHARESEG // sets segment name for this source file to SHARESEG #pragma option -zTSHARECLS // sets class name for segment to SHARECLS int SharedInteger = 0; //---- end file dllshared.cpp ----// //---- begin file dlldef.def ----// LIBRARY DLLMAIN SEGMENTS SHARESEG CLASS "SHARECLS" SHARED //---- end file dlldef.def ----// //---- Last Modified: 10-MAY-00
В Win32 библиотека DLL располагается в области памяти загружающего ее процесса. Каждому процессу предоставляется отдельная копия “глобальной” памяти DLL ( т.е делается отдельная копия всех глобальных переменных, объявленных в исходном коде этой DLL), которая реининиализируется каждый раз, когда новой процесс загружает библиотеку. Это означает, что в Win32 динамическая библиотека, вернее, ее глобальные переменные, не могут использоваться процессами совместно.
И все же, выполнив ряд замысловатых манипуляций над сегментом данных DLL, можно создать общую область памяти для всех процессов, использующих данную библиотеку.
Допустим, имеется массив целых чисел, который должен использоваться всеми процессами, загружающими некоторую библиотеку DLL. Это можно запрограммировать в коде библиотеки следующим образом:Все инициализированные переменные, объявленные между директивами #pragma data_seg (), размещаются в сегменте .MySeg. Важно специально инициализировать эти переменные, в противном случае компилятор помещает эти переменные вместо области памяти .MySeg в обычную неинициализируемую область.Code: Select all
#pragma data_seg (“.MySeg”) int sharedInts[5]={0,0,0,0,0}; // переменная общего пользования ... ... ... // другие переменные общего пользования #pragma data_seg () #pragma comment (lib, ”msvcrt” “-SECTION: .MySeg, rws”);
· Директива #pragma comment () – не обычный комментарий. Она дает указание библиотеке времени выполнения системы C пометить новый раздел как разрешенный для чтения, записи и совместного доступа (rws).
Я тут подумал, надо, видимо, сделать всё несколько иначе...Lavr wrote:Мне кажется, что вызов экспортирумой ф-ции DLL - не в потоке окна, созданного DLL-кой.
Он в потоке ехе-файла, который эту DLL-ку вызвал, поэтому переменные окна недоступны
вызываемой из DLL ф-ции.
Code: Select all
extern "C" VOID __declspec(dllexport) disp(INT arg)
{
PostMessage(hwnd, arg ... );
}
Code: Select all
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// отрисовать клиентскую область окна по последнему значению [b]INT arg[/b].
EndPaint(hwnd, &ps);
break;
Code: Select all
extern "C" VOID __declspec(dllexport) disp(INT arg)
{
...
}
Code: Select all
disp(0х0000ЕЕАА);
Code: Select all
push 00000eeaa ; аргумент (INT arg) - в стеек
call .000401020 ; вызов jmp disp
add esp,004 ; очищаем стек на 4 байта
.00401020: jmp disp ;injected.dll
Code: Select all
extern "C" VOID __declspec(dllexport) disp(INT arg)
{
arg = 0х0000ffff // - заношу значение прямо в аргумент
...
}
Code: Select all
extern "C" VOID __declspec(dllexport) disp(INT arg)
{
arg += 255;
Sleep(arg);
}
Code: Select all
.10001000: 8B442404 mov eax,[esp][00004]; - это arg из стека
.10001004: 05FF000000 add eax,0000000FF ; arg += 255;
.10001009: 50 push eax; передаем arg функции Sleep
.1000100A: FF1574D10010 call Sleep ;KERNEL32.dll
Но если хорошо подумать, то, пожалуй, можно это и сделать...Lavr wrote:Чисто опытным путём получается, что аргумент, переданный по значению вызываемая функция не изменяет.
Code: Select all
.10001000: 8B442404 mov eax,[esp][00004]; - это arg из стека
.10001004: 05FF000000 add eax,0000000FF ; arg += 255;
.10001009: 50 push eax; передаем arg функции Sleep
.1000100A: FF1574D10010 call Sleep ;KERNEL32.dll
Code: Select all
mov [esp][00004],eax; - arg обратно в стек
Code: Select all
word keyArray[4][13] = ....... ?
Угу:Lavr wrote:Shaos, двумерный массив в С++ можно как-то инициаллизировать сразу при объявлении его одной строкой?Он мне нужен как глобальный и сразу проинициаллизированный нулями.Code: Select all
word keyArray[4][13] = ....... ?
Code: Select all
word keyArray[4][13] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0}
};
Спасибо!... что-то я сам не допер...Shaos wrote:Code: Select all
word keyArray[4][13] = { {0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0} };