Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Передать строку в DLL / 15 сообщений из 15, страница 1 из 1
07.06.2017, 10:51:49
    #39467613
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Привет форумчанам. Помогите с динамической загрузкой DLL. Вроде бы загружаю правильно, но вываливается ошибка "Access violation..."


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
var
  Form1: TForm1;
  fdll_gfv: PWChar = 'GetFileVersion';
  GetFileVersion: TGetFileVersion;
  dll_inGfv: THandle;

  str_dll:  PWChar = 'fgfv.dll';
  str_file: string = 'C:\Users\Home\Desktop\Project\Debug\Win32\Project1.exe';


procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    dll_inGfv:= LoadLibrary(str_dll);
    if dll_inGfv <> 0 then
      begin
        //dll_inGfv:= LoadLibrary(str_dll);   --- если здесь загружаю, дополнительно к тому, что загрузил выше, то ошибка пропадает.       
        @GetFileVersion := GetProcAddress(dll_inGfv, fdll_gfv);
        if addr (GetFileVersion) <> nil then
          begin
            ListBox1.Items.Clear;
            ListBox1.Items.Add(GetFileVersion(str_file));
          end
        else
          begin
            ShowMessage ('Необходимая функция не найдена!');
          end;
      end
    else
      begin
        ShowMessage ('Библиотека '+str_dll+' не найдена!');
      end;
  finally
    FreeLibrary(dll_inGfv);
  end;
end;
...
Рейтинг: 0 / 0
07.06.2017, 10:53:28
    #39467614
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Код: pascal
1.
2.
3.
4.
5.
6.
type
  TGetFileVersion = function (const fn: String): String;

var
  Form1: TForm1;
...
...
Рейтинг: 0 / 0
07.06.2017, 11:00:49
    #39467624
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Valdemarius
Код: pascal
1.
2.
3.
4.
5.
6.
type
  TGetFileVersion = function (const fn: String): String; stdcall ; { <--- КАК МИНИМУМ ! }

var
  Form1: TForm1;
...
...
Рейтинг: 0 / 0
07.06.2017, 11:01:49
    #39467625
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
и да, строки так не передаются.
Надо в DLL добавить менеджер BorlandMM, если это твоя DLL.
А если не твоя, то STRING в DLL передавать нельзя.
Надо PChar, например
...
Рейтинг: 0 / 0
07.06.2017, 12:22:05
    #39467734
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
defecatorи да, строки так не передаются.
Надо в DLL добавить менеджер BorlandMM, если это твоя DLL.
А если не твоя, то STRING в DLL передавать нельзя.
Надо PChar, например

Если это его DLL то и stdcall не нужен
...
Рейтинг: 0 / 0
07.06.2017, 12:31:56
    #39467743
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
type
  TGetFileVersion = function (const fn: PChar): String; stdcall;

var
  Form1: TForm1;
  fdll_gfv: PWChar = 'GetFileVersion';
  GetFileVersion: TGetFileVersion;
  dll_inGfv: THandle;
  str_dll:  PWChar = 'fgfv.dll';
  str_file: string = 'C:\Users\Home\Desktop\Project\Debug\Win32\Project1.exe';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    dll_inGfv:= LoadLibrary(str_dll);
    if dll_inGfv <> 0 then
      begin
        //dll_inGfv:= LoadLibrary(str_dll); --- если разкомментировать, то ошибка пропадает (функция выполняется, но нет ошибки)
        @GetFileVersion := GetProcAddress(dll_inGfv, fdll_gfv);
        if addr (GetFileVersion) <> nil then
          begin
            ListBox1.Items.Clear;
            ListBox1.Items.Add(GetFileVersion(PChar(str_file)));
          end
        else
          begin
            ShowMessage ('Необходимая функция не найдена!');
          end;
      end
    else
      begin
        ShowMessage ('Библиотека '+str_dll+' не найдена!');
      end;
  finally
    FreeLibrary(dll_inGfv);
  end;
end;

end.




Функция в DLL:


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
var
  tmp, InfoSize, FileInfoSize: DWord;
  Info: Pointer;
  FileInfo: PVSFixedFileInfo;

{ Объявляем функцию GetFileVersion }
function GetFileVersion(const fn: PChar): String; stdcall;
begin
  // Функция получает информацию о файле
  result:='';
  FileInfo:=nil;
  InfoSize:=GetFileVersionInfoSize(pChar(fn), tmp);
  if InfoSize = 0 then Exit;
  GetMem(Info, InfoSize);
  GetFileVersionInfo(pChar(fn), 0, InfoSize, Info);
  VerQueryValue(Info, '\', Pointer(FileInfo), FileInfoSize);
  with FileInfo^ do
    result:=inttostr(dwProductVersionMS shr 16)     +'.'
            +inttostr(dwProductVersionMS and $FFFF) +'.'
            +inttostr(dwProductVersionLS shr 16)    +'.'
            +inttostr(dwProductVersionLS and $FFFF);
  FreeMem(Info, InfoSize);
end;

{ Экспортируем функцию для дальнейшего
  использования }
exports
  GetFileVersion;

begin
end.




После выполнения функции, подтягиваемой из DLL и получения результата - вываливается ошибка "Access violation..."
...
Рейтинг: 0 / 0
07.06.2017, 12:39:30
    #39467755
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Вопрос в том, что я, получается, чтобы исключить ошибку, дважды подгружаю DLL

Код: pascal
1.
2.
3.
4.
    dll_inGfv:= LoadLibrary(str_dll);
    if dll_inGfv <> 0 then
      begin
        //dll_inGfv:= LoadLibrary(str_dll); --- если разкомментировать, то ошибка пропадает (функция выполняется, но нет ошибки)




В этом случае выполняется функция и после ее выполнения ошибка не вываливается. Если я подгружаю только однократно, то после выполнения функции вываливается ошибка "Access..."

... а выгружаю однократно. Дважды загрузив DLL и выгрузив однократно - все ли будет правильно?

Код: pascal
1.
2.
3.
  finally
    FreeLibrary(dll_inGfv);
  end;



Про "STRING в DLL передавать нельзя" - как переработать функцию не понимаю...
...
Рейтинг: 0 / 0
07.06.2017, 12:47:34
    #39467765
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Результат с выводом информации о версии файла я получаю в любом случае. Просто ошибку надо как-то исключить. Исключить можно дважды подгрузив DLL, но выгружаю DLL я однократно.

Хотелось бы чтобы корректно работал вызов функции, корректно подгружалась и выгружалась библиотека... Наверное как у всех. :)
...
Рейтинг: 0 / 0
07.06.2017, 13:15:03
    #39467801
ziv-2014
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
ValdemariusПро "STRING в DLL передавать нельзя" - как переработать функцию не понимаю...

Используй WideString.
...
Рейтинг: 0 / 0
07.06.2017, 13:16:00
    #39467804
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Valdemarius
Код: pascal
1.
TGetFileVersion = function (const fn: PChar): String; stdcall;

defecatorи да, строки так не передаются.
Надо в DLL добавить менеджер BorlandMM, если это твоя DLL.
А если не твоя, то STRING в DLL передавать нельзя.
...
Рейтинг: 0 / 0
07.06.2017, 13:24:46
    #39467813
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
ziv-2014ValdemariusПро "STRING в DLL передавать нельзя" - как переработать функцию не понимаю...

Используй WideString.



Код: pascal
1.
2.
{ Объявляем функцию GetFileVersion }
function GetFileVersion(const fn: WideString): WideString; stdcall;




Все отлично! Благодарю Вас за помощь! )
...
Рейтинг: 0 / 0
07.06.2017, 13:35:33
    #39467821
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
_Vasilisk_Valdemarius
Код: pascal
1.
TGetFileVersion = function (const fn: PChar): String; stdcall;

defecatorи да, строки так не передаются.
Надо в DLL добавить менеджер BorlandMM, если это твоя DLL.
А если не твоя, то STRING в DLL передавать нельзя.




Надо в DLL добавить менеджер BorlandMM - если не трудно, то подскажите, как это сделать (относительно данного примера) и какую функцию он будет выполнять? Это, насколько я правильно нашел информацию, dll. Такая же DLL есть у меня...
...
Рейтинг: 0 / 0
07.06.2017, 14:27:44
    #39467850
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Valdemarius_Vasilisk_пропущено...
пропущено...





Надо в DLL добавить менеджер BorlandMM - если не трудно, то подскажите, как это сделать (относительно данного примера) и какую функцию он будет выполнять? Это, насколько я правильно нашел информацию, dll. Такая же DLL есть у меня...

Uses Sharemem первым модулем в DLL и в проекте
...
Рейтинг: 0 / 0
07.06.2017, 14:49:11
    #39467874
Valdemarius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
schiValdemariusпропущено...





Надо в DLL добавить менеджер BorlandMM - если не трудно, то подскажите, как это сделать (относительно данного примера) и какую функцию он будет выполнять? Это, насколько я правильно нашел информацию, dll. Такая же DLL есть у меня...

Uses Sharemem первым модулем в DLL и в проекте




Согласен. Надо быть внимательнее... В заголовке проекта DLL (библиотеки) об этом описано "комментарий на английском" )

Код: pascal
1.
2.
3.
library Project1;

{ Important note about DLL memory management: ShareMem...



На этот счет есть (как по мне) хорошая статья на: cyberguru ru / delphi / strings-details-page8 html

Благодарю schi за помощь! )
...
Рейтинг: 0 / 0
07.06.2017, 15:50:53
    #39467936
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передать строку в DLL
Код: pascal
1.
function SomeFunction(S: string): string; external 'strlib.dll';



http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Procedures_and_Functions_(Delphi)
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Передать строку в DLL / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]