Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Загрузка библиотеки и функций из неё / 12 сообщений из 12, страница 1 из 1
11.06.2018, 16:43
    #39659478
Ss`st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Делаю проект, аудитория 200 человек. И на днях обратился ко мне пользователь, сказал что у него ничего не работает (AV)

Опытным путём было выявлено, что библиотека собранная на c++ не в какую не хочет у него работать (Не найдена dll)

От админа запуск приводил к AV

Я пересоздал все импорты со стандартной загрузки ; cdecl; external libraryPath name 'NameFunction';

На
Код: 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.
function HRESULTStr(h: HRESULT): LPWSTR;
begin
  FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
    nil, h, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @result, 0, nil);
end;

procedure LoadPHPFunc(var func: pointer; FuncName: LPCSTR);
const
  dll = 'DllName.dll';
begin
  if DllHandle = 0 then
    if FileExists(dll) then
    begin
      DllHandle := GetModuleHandlew(dll);
      if DllHandle = 0 then
        DllHandle := LoadLibraryw(dll);
      if DllHandle = 0 then
      begin
        ShowMessage('Не смог иницилизировать библиотеку (' + dll + ')' +
          HRESULTStr(GetLastError) + #10#13 + '- ' + dll);

        Exit;
      end;
    end;

  func := GetProcAddress(DllHandle, FuncName);
  if not assigned(func) then
    MessageBoxW(0, Pchar('Unable to link [' + FuncName + '] function'),
      'LoadFunction', 0);
end;




И того, без прав админа выводится сообщение "Не смог инициализировать библиотеку (DllName.dll) - DllName.dll"

При запуске от админа Unable to link [FunctionName] function


В чём может быть проблема ?
...
Рейтинг: 0 / 0
11.06.2018, 17:07
    #39659487
Лисъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Ставлю на то, что DLL-ка не может подгрузить свои зависимости (например не установлена корректная версия сишного рантайма).

Смотри от чего зависит DLL-ка: туд
...
Рейтинг: 0 / 0
11.06.2018, 17:08
    #39659488
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Ss`stВ чём может быть проблема ?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.
procedure LoadPHPFunc(var func: pointer; FuncName: LPCSTR);
const
  dll = 'DllName.dll';
begin
  if DllHandle = 0 then
    if FileExists(dll) then
    begin
      DllHandle := LoadLibraryw(dll);
      if DllHandle = 0 then
      begin
        ShowMessage('Не смог иницилизировать библиотеку (' + dll + ')' +
          HRESULTStr(GetLastError) + #10#13 + '- ' + dll);

        Exit;
      end;
    end else begin
        ShowMessage('Файл ' + dll + ' не найден');
        Exit;
    end;

  func := GetProcAddress(DllHandle, FuncName);
  if not assigned(func) then
    MessageBoxW(0, Pchar('Unable to link [' + FuncName + '] function'),
      'LoadFunction', 0);
end;


А еще лучше так
Код: 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.
procedure RaiseLastOSErrorEx(const AMsg: string);
var
  Code: Cardinal;
  Err: EOSError;
begin
  Code := GetLastError;
  Err := EOSError.CreateFmt('%s: %s (%u)', AMsg, SysErrorMessage(Code), Code);
  Err.ErrorCode := Code;
  raise Err;
end;

procedure LoadPHPFunc(var func: pointer; FuncName: PChar);
const
  dll = 'DllName.dll';
begin
  if DllHandle = 0 then
    if not FileExists(dll) then
      raise Exception.Create('Файл ' + dll + ' не найден');
    DllHandle := LoadLibrary(dll);
    if DllHandle = 0 then
      RaiseLastOSErrorEx('Не смог иницилизировать библиотеку (' + dll + ')');
  func := GetProcAddress(DllHandle, FuncName);
  if not Assigned(func) then
    RaiseLastOSErrorEx(Format('Unable to link [%s.%s] function', [dll, FuncName]))
end;
...
Рейтинг: 0 / 0
11.06.2018, 17:15
    #39659490
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
И еще. Этот код
_Vasilisk_
Код: pascal
1.
2.
    if not FileExists(dll) then
      raise Exception.Create('Файл ' + dll + ' не найден');

можно использовать только в том случае, если dll ожидается в текущем каталоге. В противном случае этот кусок вреден и его нужно убрать.

А если dll ищется только в каталоге программы, то тогда код нужно переписать так

_Vasilisk_
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
procedure LoadPHPFunc(var func: pointer; FuncName: PChar);
const
  dll = 'DllName.dll';
var
  fullName: string;
begin
  if DllHandle = 0 then begin
    fullName := ExtractFilePath(GetModuleName(HInstance)) + dll;
    if not FileExists(fullName) then
      raise Exception.Create('Файл ' + fullName + ' не найден');
    DllHandle := LoadLibrary(fullName);
    if DllHandle = 0 then
      RaiseLastOSErrorEx('Не смог иницилизировать библиотеку (' + fullName + ')');
  end;
  func := GetProcAddress(DllHandle, FuncName);
  if not Assigned(func) then
    RaiseLastOSErrorEx(Format('Unable to link [%s.%s] function', [dll, FuncName]))
end;
...
Рейтинг: 0 / 0
11.06.2018, 18:00
    #39659497
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
_Vasilisk_,

Там есть нюанс с dll. Если dll (например host) тянет за собой еще какую-то dll (slave) и находится не в каталоге программы, то эту вторую slave.dll нужно грузить или по абсолютному пути или ложить рядом с .exe, но не рядом с host.dll.
...
Рейтинг: 0 / 0
11.06.2018, 18:36
    #39659508
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
DarkMasterТам есть нюанс с dll. Если dll (например host) тянет за собой еще какую-то dll (slave) и находится не в каталоге программы, то эту вторую slave.dll нужно грузить или по абсолютному пути или ложить рядом с .exe, но не рядом с host.dll.Извини, но в такой формулировке написан бред

Все dll, используемые процессом должны лежать по известным путям

If SafeDllSearchMode is enabled, the search order is as follows:

The directory from which the application loaded.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

If SafeDllSearchMode is disabled, the search order is as follows:

The directory from which the application loaded.
The current directory.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.или должны быть загружены с указанием полного пути
...
Рейтинг: 0 / 0
11.06.2018, 19:57
    #39659520
Ss`st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Нашли причину. Проблема была в том, что система не могла найти 32 битный vcruntime140.dll

Но у пользователя он был установлен! Той же версии. Проблема решилась после того, как vcruntime140.dll попал в папку с исполняемым файлом.


Непонятно почему,нигде не было выведено ошибок об отсутствие этой библиотеки, или невозможности загрузить 64 битную версию vcruntime140.dll
...
Рейтинг: 0 / 0
11.06.2018, 21:05
    #39659534
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Ss`stНо у пользователя он был установлен!И где он находился?
Ss`stНепонятно почему,нигде не было выведено ошибок об отсутствие этой библиотекиЭто вам лучше знать, почему вы не выводили код ошибки
Ss`stили невозможности загрузить 64 битную версию vcruntime140.dllА с какого перепугу в 32 битный процесс будет загружаться 64 битная dll?
...
Рейтинг: 0 / 0
11.06.2018, 21:35
    #39659537
Ss`st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
_Vasilisk_И где он находился?

По умолчанию загрузка происходит (У пользователя)
(Microsoft® C Runtime Library) F:\Windows\System32\VCRUNTIME140.dll : 14.14.26429.4 (64 bit 85,8 КБ (87 872 байт))

У меня - же, загрузка происходит по пути
(Microsoft® C Runtime Library) C:\Windows\SysWOW64\VCRUNTIME140.dll : 14.14.26429.4 (64 bit. 85,3 КБ (87 360 байт))

_Vasilisk_Это вам лучше знать, почему вы не выводили код ошибки

Действительно, почему я не выводил код ошибки?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
function HRESULTStr(h: HRESULT): LPWSTR;
begin
  FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
    nil, h, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @result, 0, nil);
end;

....
  ShowMessage('Не смог иницилизировать библиотеку (' + dll + ')' +
          HRESULTStr(GetLastError) + #10#13 + '- ' + dll);




_Vasilisk_А с какого перепугу в 32 битный процесс будет загружаться 64 битная dll?

И я не знаю,почему у пользователя 32 битное приложение пыталась загрузить 64 битную версию библиотеки (Запуская процесс от администратора)
Потому как, запуская с правами обычного пользователя, был вывод о не найденной библиотеки
...
Рейтинг: 0 / 0
11.06.2018, 21:37
    #39659538
Ss`st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Ss`stПотому как, запуская с правами обычного пользователя, был вывод о не найденной библиотеки

Уточню, не найденной библиотеки - которую я пытаюсь использовать, а не эту VCRUNTIME140.dll

И это притом, что это было при использование " ; cdecl; external libraryPath name 'NameFunction';"
...
Рейтинг: 0 / 0
11.06.2018, 21:41
    #39659540
Ss`st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Решил с копипастить и быстро прописать, и допустил маленькую ошибку в описание (Так как я удалил уже информационный вывод, а он остался в переписки - с пользователем)

Ss`stПо умолчанию загрузка происходит (У пользователя)
(Microsoft® C Runtime Library) F:\Windows\System32\VCRUNTIME140.dll : 14.14.26429.4 (64 bit 85,8 КБ (87 872 байт))

У меня - же, загрузка происходит по пути
(Microsoft® C Runtime Library) C:\Windows\SysWOW64\VCRUNTIME140.dll : 14.14.26429.4 ( 32 bit. 85,3 КБ (87 360 байт))
...
Рейтинг: 0 / 0
11.06.2018, 23:30
    #39659557
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загрузка библиотеки и функций из неё
Ss`stДействительно, почему я не выводил код ошибки?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
function HRESULTStr(h: HRESULT): LPWSTR;
begin
  FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
    nil, h, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @result, 0, nil);
end;

....
  ShowMessage('Не смог иницилизировать библиотеку (' + dll + ')' +
          HRESULTStr(GetLastError) + #10#13 + '- ' + dll);


Вот и мне интересно
Ss`st
Код: 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.
procedure LoadPHPFunc(var func: pointer; FuncName: LPCSTR);
const
  dll = 'DllName.dll';
begin
  if DllHandle = 0 then
    if FileExists(dll) then  // else не обнаружено
    begin
      DllHandle := GetModuleHandlew(dll);
      if DllHandle = 0 then
        DllHandle := LoadLibraryw(dll);
      if DllHandle = 0 then
      begin
        ShowMessage('Не смог иницилизировать библиотеку (' + dll + ')' +
          HRESULTStr(GetLastError) + #10#13 + '- ' + dll);

        Exit;
      end;
    end;

  func := GetProcAddress(DllHandle, FuncName);
  if not assigned(func) then
    MessageBoxW(0, Pchar('Unable to link [' + FuncName + '] function'),
      'LoadFunction', 0);
end;


Ss`stИ я не знаю,почему у пользователя 32 битное приложение пыталась загрузить 64 битную версию библиотеки (Запуская процесс от администратора)
Потому как, запуская с правами обычного пользователя, был вывод о не найденной библиотекиПорядок поиска я указал 21484830 а теперь смотрите, как в этом списке оказался 64 System32 вместо 32 битного SysWOW64. Одна из причин - в SysWOW64 dll не было, а System32 был занесен в Path
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Загрузка библиотеки и функций из неё / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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