Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

FreeLibrary [D5, D6, D7, Win2k, WinXP]


Страницы:   1 2

ZHK ©   (2004-06-21 10:31:00) 

Здравствуйте, Господа.
Попал в затруднительную ситуацию. Тупею. :-) Вот кусок кода:


procedure TForm1.Button3Click(Sender: TObject);
var
 DialogCount:TDialogCount;
 DialogName:TDialogName;
 DialogDescription:TDialogDescription;
 DialogExecute:TDialogExecute;
 SetDatabaseList:TSetDatabaseList;
 LH:THandle;
 SQL:TStrings;
begin
//  Form6.Execute;
 LH:=LoadLibrary('dll\sql1\SQL1.dll');
 @DialogCount := GetProcAddress(LH,'DialogCount');
 @DialogName := GetProcAddress(LH,'DialogName');
 @DialogDescription := GetProcAddress(LH,'DialogDescription');
 @DialogExecute := GetProcAddress(LH,'DialogExecute');
 @SetDatabaseList := GetProcAddress(LH,'SetDatabaseList');
 if Assigned(SetDatabaseList) then
    SetDatabaseList(PostgreSQLConnectionForm.ListBox1.Items);
 SQL:=TStringList.Create;
 if Assigned(DialogExecute) then
    begin
      DialogExecute(0,SQL);
      if SQL.Count>0 then
         RichEdit1.Lines.Assign(SQL);
    end;
 SQL.Free;

 FreeLibrary(LH);  
{
А вот тут-то и возникает ошибка Invalid Floating Point Operation.
При необходимости могу прислать полный проект DLL-ки. Мое мыло - eug_elizarov@mail.ru
}

end;

Кто чем может. :-)


evvcom   (2004-06-22 12:53:00) [1]


> на самом деле не -1, а максимальное значение DWORD

В двоичной арифметике - это одно и то же.

И все же внимательнее чти [27] и [29]


panov   (2004-06-22 11:12:00) [2]

>ZHK ©   (22.06.04 09:16) [28]

var
LH:THandle=INVALID_HANDLE_VALUE;

Это спасает от многого.


var
LH:THandle=0;

if LH=0 then LoadLibrary(...)

спасает значительно лучше...


ZHK   (2004-06-22 09:16:00) [3]

Спасибо, я знаю, чему равно значение INVALID_HANDLE_VALUE. А DWORD(-1) на самом деле не -1, а максимальное значение DWORD. Конечно же, это не совсем корректно, я согласен, но я не думаю что при моей жизни я когда нибудь достигну максимального значения хэндла, потому спокоен за этот код. А что до инициализации, то это делается просто:

var
 LH:THandle=INVALID_HANDLE_VALUE;

Это спасает от многого.


evvcom   (2004-06-22 00:07:00) [4]

И еще:

const
 INVALID_HANDLE_VALUE = DWORD(-1);

тогда как
LoadLibrary
If the function fails, the return value is NULL.

И изначально LH где-то нужно инициализировать в INVALID_HANDLE_VALUE. Лучше этого не делать и проверять на незагруженность библиотеки, сравнивая с 0, а не с -1.


Игорь Шевченко   (2004-06-21 14:43:00) [5]


> ShareMem, насколько я понял, необходим только для правильной
> работы со строками


И с классами, которые используют строки, например TStringList


ZHK   (2004-06-21 14:40:00) [6]

Надо, только не в этом дело. Я понял. :-) Я ж говорю - тупею.

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
 FH:THandle;
 I:Integer;
begin
 if CmdFileName<>'' then
    begin
      FH:=FileCreate(CmdFileName);
      for I:=0 to Length(Cmd)-1 do
        begin
          FileWrite(FH,Z[1],1);
          FileWrite(FH,Cmd[I][1],Length(Cmd[I]));
        end;
      FileClose(FH);
    end;
 if LH<>INVALID_HANDLE_VALUE then
    begin
      FreeLibrary(LH);
      LH:=INVALID_HANDLE_VALUE;
//Вот этой строчки-то и не было.
    end;
end;

То есть окно, закрываясь, выгружало библиотеку, а повторная загрузка - не производилась. Понятно, что обращаясь к несуществующей функции ошибка-то и происходила. :-) А ShareMem, насколько я понял, необходим только для правильной работы со строками. Если использовать PChar, как я это делал, то он не обязателен. Спасибо за помощь!


Игорь Шевченко   (2004-06-21 14:33:00) [7]


>  TDialogGetSQL=function (Index:Integer):PChar;


stdcall не надо ?


ZHK   (2004-06-21 14:27:00) [8]

А сейчас уже это выглядит вот так:

program SQLShell;

uses
ShareMem,
Forms,
Windows,
MainUnit in 'MainUnit.pas' {PostgreSQLConnectionForm},
Connection in '..\Useful\PGQuery\Connection.pas',
ResOut in 'ResOut.pas' {ResOutForm},
SQLInput in 'SQLInput.pas' {Form1},
TextForm in 'TextForm.pas' {Form2},
DatabaseSel in 'DatabaseSel.pas' {Form3},
Logged in 'Logged.pas' {Form4},
Options in 'Options.pas' {Form5},
LoadHd in 'LoadHd.pas' {LoadHead},
SQLSelector in 'SQLSelector.pas' {Form6},
LoadPages in 'LoadPages.pas';


После всех перетрубаций первый вызов функций загруженной библиотеки успешен, повторный вызов - приводит к ошибке Access violation...

А вообще вызов преобразился следующим образом:

procedure TForm1.Button3Click(Sender: TObject);
var
 SQL:String;
begin
//  Form6.Execute;
 if LH=INVALID_HANDLE_VALUE then
    begin
      LH:=LoadLibrary('dll\sql1\SQL1.dll');
      @DialogCount := GetProcAddress(LH,'DialogCount');
      @DialogName := GetProcAddress(LH,'DialogName');
      @DialogDescription := GetProcAddress(LH,'DialogDescription');
      @DialogExecute := GetProcAddress(LH,'DialogExecute');
      @SetDatabaseList := GetProcAddress(LH,'SetDatabaseList');
      @DialogGetSQL := GetProcAddress(LH,'DialogGetSQL');
    end;
 if Assigned(SetDatabaseList) then
    SetDatabaseList(PChar(PostgreSQLConnectionForm.ListBox1.Items.Text));
 if Assigned(DialogExecute) then
    if DialogExecute(0) then
       begin
         SQL:=String(DialogGetSQL(0));
         RichEdit1.Lines.Text:=Trim(SQL);
       end;
end;

и добавился тип:

 TDialogGetSQL=function (Index:Integer):PChar;


Игорь Шевченко   (2004-06-21 14:24:00) [9]


>
> program SQLShell;
>
> uses
  ShareMem,>  Forms,
>  Windows,


ZHK   (2004-06-21 14:17:00) [10]


program SQLShell;

uses
 Forms,
 Windows,
 MainUnit in 'MainUnit.pas' {PostgreSQLConnectionForm},
 Connection in '..\Useful\PGQuery\Connection.pas',
 ResOut in 'ResOut.pas' {ResOutForm},
 SQLInput in 'SQLInput.pas' {Form1},
 TextForm in 'TextForm.pas' {Form2},
 DatabaseSel in 'DatabaseSel.pas' {Form3},
 Logged in 'Logged.pas' {Form4},
 Options in 'Options.pas' {Form5},
 LoadHd in 'LoadHd.pas' {LoadHead},
 SQLSelector in 'SQLSelector.pas' {Form6},
 LoadPages in 'LoadPages.pas';


Игорь Шевченко   (2004-06-21 14:01:00) [11]

uses от .dpr покажи :)


ZHK   (2004-06-21 13:56:00) [12]


> Anatoly Podgoretsky ©   (21.06.04 13:33) [18]
> ZHK ©   (21.06.04 13:26) [16]
> Тебя же просилм все USES, не надо это делать по кускам.

Наверное я что-то не понял. Все usesсо ВСЕХ ВХОДЯЩИХ В ПРОЕКТ МОДУЛЕЙ?


Anatoly Podgoretsky   (2004-06-21 13:33:00) [13]

ZHK ©   (21.06.04 13:26) [16]
Тебя же просилм все USES, не надо это делать по кускам.


panov   (2004-06-21 13:29:00) [14]

см. Игорь Шевченко ©   (21.06.04 13:15) [14]

Нужно в файл проекта добавить первым в uses.


ZHK   (2004-06-21 13:26:00) [15]

В library я уже выше привел, а в модуле вот такой:

unit SQLInput;

interface

uses
 ShareMem, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls, ComCtrls;


Anatoly Podgoretsky   (2004-06-21 13:19:00) [16]

Ты приведи сначала свои USES


Игорь Шевченко   (2004-06-21 13:15:00) [17]


> И в модуле, где библиотека вызывается, он тоже первым стоит...


Надо в .dpr


ZHK   (2004-06-21 13:11:00) [18]

Дык я ж его первым и поставил... А ошибка то не ушла... Да. И в модуле, где библиотека вызывается, он тоже первым стоит...


Игорь Шевченко   (2004-06-21 12:24:00) [19]


> ShareMem must be the
> first unit in your library's USES clause ANDyour project's
> (select
> Project-View Source) USES clause


ZHK   (2004-06-21 12:15:00) [20]


library SQL1;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses

ShareMem,

SysUtils,
Classes,
Billing in 'Billing.pas' {Form1},
SQLTypes in '..\SQLTypes.pas';



Очевидно, что сделал что-то не так. Подскажите...


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо