|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Вызов одной DLL из нескольких потоков
Привет всем. Не спрашивайте зачем
При создании одного потока - все работает прекрасно и без ошибок. Если потоков 2 и больше - либо вылетает, либо сыпется различного рода ошибками, типа EAccessViolation или EInvalidPointer. Буду очень благодарен, если направите мысли в нужное русло! Всем спасибо! Код DLL: Код:
library gear; uses System.SysUtils, System.Net.HttpClientComponent, System.Net.HttpClient, System.Net.URLClient; {$R *.res} function Execute: Integer; stdcall; var PResponse: IHTTPResponse; begin with TNetHTTPClient.Create(nil) do try PResponse := GET('https://www.google.com/'); Result := PResponse.StatusCode; finally PResponse := nil; free end; end; exports Execute; begin end. Код:
unit TestThreadUnit; interface uses Windows, SysUtils, Classes; type TExecute = function(): Integer; TestThread = class(TThread) protected I: Integer; procedure Execute; override; public constructor Create; procedure Sync; end; implementation uses TestUnit; constructor TestThread.Create; begin inherited Create(false); end; procedure TestThread.Execute; var hndDLLHandle: THandle; Ex: TExecute; begin try hndDLLHandle := loadLibrary('gear.dll'); if hndDLLHandle <> 0 then begin @Ex := getProcAddress(hndDLLHandle, 'Execute'); if addr(Ex) <> nil then I := Ex() else I := -1; end else I := -1; finally freeLibrary(hndDLLHandle); Synchronize(Sync); end; end; procedure TestThread.Sync; begin TestForm.Memo1.Lines.Add(I.ToString); end; end. Код:
unit TestUnit; interface uses System.Classes, Vcl.Controls, Vcl.Forms, Vcl.StdCtrls; type TTestForm = class(TForm) ThreadButton: TButton; Memo1: TMemo; procedure ThreadButtonClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var TestForm: TTestForm; implementation uses TestThreadUnit; {$R *.dfm} procedure TTestForm.ThreadButtonClick(Sender: TObject); var m: integer; begin // for m := 0 to 1 do TestThread.Create.FreeOnTerminate := true; end; end. |
#2
|
|||
|
|||
1. В описании типа функции так же укажи stdcall. В твоем случае это не должно быть проблемой, т.к. это больше влияет на передачу параметров, но все-таки.
2. Мне не нравится, что ты пытаешься грузить библиотеку несколько раз. Попробуй вынести загрузку библиотеки и ее освобождение из потока (пока для проверки - сделай глобальную переменную для хэндла, а саму загрузку и выгрузку просто вынеси в секции initialize и finalize модуля, если все полечится, то потом можно будет переписать почеловечески). |
#3
|
|||
|
|||
Цитата:
Runtime Packages галка снята Последний раз редактировалось darkwellroad, 22.11.2019 в 17:19. |
#4
|
|||
|
|||
BPL - значит сами компоненты зависимы от VCL.
Если тебе надо просто получитьт код возврата, то попробуй вместо этих компонентов воспользоваться Indy (да, придется таскать за собой пару dll для поддержки ssl, ну или нарыть код для включеия их в exe/dll, но они не большие). |