Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.08.2013, 08:41
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию Работа со строками в DLL

Добрый день.

Код длл:

Код:
library MYDLL;

uses
  SysUtils, Registry,
  Windows; 

var Buffer: PWideChar;
  
decision: integer;

function DoThings: integer;
var
  MemoryStatus : TMemoryStatus;
  SysInfo: TSystemInfo;
  i, sdviger, sdvig, ggd, ssum, tRes:integer;
  reg: TRegistry;
  mas, mas2, key, tStr, s: WideString;
begin
  sdviger:=2;
  sdvig:=3;
  mas:= '22222rrrrrllllldddddkkkkcccccoooooqqqqqpppppbbbbbjjjjjmmmmmaaa';
  mas2:='nnnnnmmmmmsssspppppqqqqqkkkkkgggggglllllbbbbbxxxxxyyyyyaaaaann';
  key:='';

  try
    reg:=tregistry.Create;
    reg.RootKey:=HKEY_LOCAL_MACHINE;
    reg.OpenKey('\hardware\description\system',true);
    key:=reg.readString('SystemBiosdate');
    reg.Free;
  except
    on exception do sdvig:=sdvig;
  end;
  //if key<>'02/04/10' then MessageBox(0,PWideChar(key+' 02/04/10'), 'terminal', MB_OK);

  MemoryStatus.dwLength := SizeOf(MemoryStatus);
  GlobalMemoryStatus(MemoryStatus);
  With MemoryStatus do
  Begin
    dwTotalPhys := dwTotalPhys DIV 1024;
    ssum:=dwTotalPhys;
    tStr:=IntToStr(dwTotalPhys)+key;
  End;

  //вот здесь tStr принимает чужие значения
.
.
.
end;

function MainFunc: integer; stdcall;
begin
  result:=DoThings;
end;

//----------------------------------------------------------+
exports
  GetStringBuffer, BenefitEAFunc;

procedure DLLEntryPoint(dwReason: DWord); // обработчик событий
begin
    case dwReason of

      DLL_PROCESS_ATTACH: // DLL присоединена к процессу;
          // выделение памяти
          Buffer:=AllocMem(255);
          //decision:=DoThings;

      DLL_PROCESS_DETACH: // DLL отсоединена от процесса;
          // освобождение памяти
          FreeMem(Buffer);

    end;
end;

begin
    IsMultiThread := True;
    DllProc := @DLLEntryPoint; //Назначение процедуры обработки событий
    DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

Эта библиотека используется в разных потоках одной программы. Из этих потоков вызывается одна и та же ф-я библиотека, которая всегда для любого потока возвращает одно и то же значение.
Но в коде, в месте которое я пометил комментарием "вот здесь tStr принимает чужие значения" иногда эта строка принимает посторонние значения. При чем не значение этой переменной соседнего потока.

Подскажите пожалуйста решение.
1. Как сделать глобальную переменную в DLL что бы запускать эту функцию всего лишь раз для всех потоков?
2. Если первый вариант не возможен, как сделать эту процедуру мультипоточной, что бы строковая переменная одного потока не "затиралась" другим потоком?
Ответить с цитированием
  #2  
Старый 12.08.2013, 10:20
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

А в чём смысл такого кода?
Код:
         DLL_PROCESS_ATTACH: // DLL присоединена к процессу;
           // выделение памяти
           Buffer:=AllocMem(255);
           //decision:=DoThings;
         DLL_PROCESS_DETACH: // DLL отсоединена от процесса;
           // освобождение памяти
           FreeMem(Buffer); 
Buffer у Вас глобальная переменная, которая будет использоваться разными потоками и приведёт к большим проблемам.
например
1-й поток выполнил Buffer:=AllocMem(255); - всё нормально
2-й поток выполнил Buffer:=AllocMem(255); - будет затёрто предыдущее значение Buffer и утечка памяти. И оба потока будут параллельно использовать этот буфер с непредсказуемым результатом.
1-й поток выполнил FreeMem(Buffer); при этом унитожится массив, но ссылка на него останется в переменной Buffer, и второй поток будет пользоваться этой битой ссылкой.

Для начала попробуйте описать так

Код:
threadvar Buffer: PWideChar;     
threadvar decision: integer; 
Тогда каждый поток будет использовать свою копию переменных.
Ответить с цитированием
Этот пользователь сказал Спасибо icWasya за это полезное сообщение:
одинадцатый (12.08.2013)
  #3  
Старый 12.08.2013, 10:31
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

DLL_PROCESS_ATTACH != DLL_THREAD_ATTACH && DLL_PROCESS_DETACH != DLL_THREAD_DETACH
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #4  
Старый 12.08.2013, 10:43
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Спасибо большое за ответ.
Buffer - это вообще атавизм, она не используется.
И decision не используется. Но сама идея объявления через threadvar - наверно то что мне нужно. Только имеет смысл объявлять так переменную tStr. Т.к. именно она страдает. Но она локальная. Так имеет ли смысл? )
И так как тут используется поточность не надо ли мне как-то указать что эта DLL многопоточная?
Ответить с цитированием
  #5  
Старый 12.08.2013, 12:19
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

И можно ли все таки сделать глобальную переменную в DLL на все потоки, что бы один раз посчитать значение этой функции?
И не надо будет разбираться с памятью...
Ответить с цитированием
  #6  
Старый 12.08.2013, 13:01
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
Радость

а нужна ли вообще dll?
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #7  
Старый 12.08.2013, 15:36
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Цитата:
Сообщение от одинадцатый
И можно ли все таки сделать глобальную переменную в DLL на все потоки, что бы один раз посчитать значение этой функции?
И не надо будет разбираться с памятью...

Ну так и вызывай один раз.
А как определяешь, что
Цитата:
Сообщение от одинадцатый
//вот здесь tStr принимает чужие значения
Ответить с цитированием
  #8  
Старый 12.08.2013, 18:42
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

DLL очень нужна! )
Определяю что ошибка там через MessageBox )
Ответить с цитированием
  #9  
Старый 13.08.2013, 10:32
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Я так понимаю вопросы мои невероятно банальны и отвечать на такие ни у кого нет желания
Подскажите хотя бы хорошую книженцию по DLL на Delphi, где освещены мои глупые вопросы. Буду очень признателен.
Ответить с цитированием
  #10  
Старый 13.08.2013, 17:47
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

В виде статей, разных.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 14:20.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter