Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите разобраться с dll 
:(
    Опции темы
suvolod
Дата 17.2.2006, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 20.8.2005

Репутация: 1
Всего: 1



Помогите решить следующую задачку. В книге "Петзольда Программирование для Windows 95, том 2, глава 19" приведен пример программы, как создать dll, у которой есть некоторая общая область данных, видимая всем программам, которые используют данную dll. Выглядит этот примерно так :
Код

#pragma data_seg("shared")
PSTR pszStrings[MAX_STRINGS] = { NULL };
int iTotal = 0;
#pragma data_seg() 
#pragma comment(linker, "/section:shared,rws")

Затем приложение, которое использует данную dll, добавляет в массив pszStrings строки, и эти строки отображаются в клиентской части окна всех копий приложения, запущенных в данный момент.
Проблема заключается в том, что у меня при попытке запустить вторую копию приложения она просто вылетает. Если же убрать в коде dll строчку " #pragma comment(linker, "/section:shared,rws") ", то копия2 (и последующие) запускаются нормально, но каждый использует и выводит в окно свой собственный массив pszStrings. Работаю я под VC++ 6.0 SP6, ОС- WinXP SP1
На всякий случай - вот здесь исходники: suvolod.mail2k.ru/proect.rar . Весит немного - около 70 Kb
STRLIB - это исходники библиотеки
STRPROG - это исходники программы, использующие STRLIB.dll
PM MAIL   Вверх
Earnest
Дата 17.2.2006, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Либо в книжке ошибка, либо ты что-то не так понял.
Общая память должна охватывать каждый байт общих данных, а у тебя только адреса строкю А сами строки где хранится будут? Ясно же, что память выделенная в одном приложении, не доступна в другом... Вот она и падает.
В данном случае (если хочешь именно набор строк сделать общедоступным) нужно выделить буфер символов достаточно большого размера, и копировать строки туда.
Чтобы просто понять как работает общий сегмент данных, заведи для начала простые переменные, массив интов, например.


--------------------
...
PM   Вверх
suvolod
Дата 17.2.2006, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 20.8.2005

Репутация: 1
Всего: 1



И все-таки я не понял, в чем моя ошибка … Может кто-то глянет сам код?
Самое интересное, что я нашел-таки исходники от самого Петзольда, и у него та-же самая ошибка: если запустить, к примеру, 4 копии приложения, а затем, используя одну из них, добавить строку - все остальные копии тут-же вылетают, хотя у него ясно написано, что директива типа #pragma comment(linker, "/section:shared,rws") делает все переменные этого раздела общими… Мучает смутное подозрение, что его код тоже рабочий, но только под Windows95, а под NT такой способ создания "общего раздела" не прокатывает.

А насчет замечания "а у тебя только адреса строкю А сами строки где хранится будут" – строки добавляются к массиву pszStrings через функцию библиотеки STRLIB
На всякий случай вот ее код:
Код

//добавление строк в через DLL
EXPORT BOOL CALLBACK AddString(PSTR pStringIn)
{
HANDLE hString;
PSTR pString;
int i, iLength, iCompare;
if(iTotal == MAX_STRINGS - 1)    //общее количество строк не должно быть больше 256
return FALSE;
iLength = strlen(pStringIn);    
if(iLength == 0)            //нельзя добавлять пустую строку
return FALSE;
hString = CreateFileMapping(    //создаем спроецированный в память файл
(HANDLE) -1, NULL, PAGE_READWRITE,0, 1 + iLength, NULL);        
if(hString == NULL)                //не получилось создать
return FALSE;
pString =(PSTR) MapViewOfFile(hString,    FILE_MAP_WRITE,    0, 0, 0);
strcpy(pString, pStringIn);        //скопировали строку в проецируемый файл
AnsiUpper(pString);            //перевели в верхний регистр

for(i = iTotal; i > 0; i--)
{
iCompare = strcmpi(pStringIn, pszStrings[i - 1]);
if(iCompare >= 0)
break;
pszStrings [i] = pszStrings[i - 1];
}
pszStrings[i] = pString;
iTotal++;
return TRUE;
}


PM MAIL   Вверх
Earnest
Дата 17.2.2006, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



suvolod, pragma comment нормально работает во всех виндовсах. И не в ней суть - это всего лишь удобный способ передать опции линкеру. То же самое можно сделать и в командной строке или в настройках проекта. Суть в создании именованной секции данных и объявлении ее общей (разделяемой).
ТОЛЬКО ТО, ЧТО НАХОДИТСЯ В СЕКЦИИ, РАЗДЕЛЯЕТСЯ.
А в секции у тебя находятся АДРЕСА СТРОК, а не сами строки. Адрес строки - это просто число, с точки зрения другого экземпляра, по этому адресу ничего никогда не было.
Не знаю, почему у Петцольда это работало, возможно дело в проецированных в память файлах. Но все равно не понимаю, какой смысл указатель в MapView одного процесса может иметь в контексте другого.
Если ты в разделяемую секцию поместишь такую переменную:
char szBuf[MAX_SIZE] = "AAAAAAAAAAAAAA";
то к ее содержимому можно будет обращаться из любого экземпляра.



--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0437 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.