В вопросе пользователя описывается проблема, связанная с вызовом функции из 64-битной динамически подключаемой библиотеки (DLL) в среде разработки Delphi. Проблема заключается в возникновении исключения ACCESS_VIOLATION при попытке выполнения функции, несмотря на то, что адрес функции определен корректно.
Оригинальный заголовок:
Вызов функции из 64-битной DLL в Delphi
Описание проблемы:
Пользователь пытается перенести простой пример на C++ в среду разработки Delphi. В примере используется функция из 64-битной DLL, которая работает с устройствами и возвращает список устройств в определенном формате. После перевода структуры данных и настройки вызова функции через LoadLibrary и GetProcAddress, при попытке выполнения функции возникает исключение ACCESS_VIOLATION.
Шаги решения проблемы:
Проверка соответствия структур данных: Убедитесь, что структура dfuDeviceInfo в Delphi точно соответствует структуре из исходного C++ кода. Особое внимание следует уделить выравниванию полей структуры.
Удаление библиотеки: Не освобождайте библиотеку с помощью FreeLibrary до тех пор, пока все вызовы функций из нее не будут выполнены. Это необходимо для того, чтобы библиотека оставалась в памяти и была доступна для вызовов.
Использование сырого указателя: Вместо использования динамического массива Delphi для получения указателя на выходные данные DLL, используйте сырой указатель. Это важно, так как DLL ожидает, что вы выделите память для массива, и вернет указатель на него.
Выделение памяти: Функция getDfuDeviceList из DLL должна выделить память для массива устройств, поэтому вам не нужно заранее выделять память для dfuList.
Очистка памяти: После использования dfuList, не забудьте освободить выделенную память в соответствии с требованиями DLL или напрямую через функции операционной системы, если это необходимо.
Пример кода:
type
dfuDeviceInfo = record
usbIndex: array [0..9] of AnsiChar;
busNumber: Integer;
addressNumber: Integer;
productId: array [0..99] of AnsiChar;
serialNumber: array [0..99] of AnsiChar;
dfuVersion: UInt32;
end;
pdfuDeviceInfo = ^dfuDeviceInfo;
var
getDfuDeviceList: function(var dfuList: pdfuDeviceInfo; iPID: Integer; iVID: Integer): Integer; cdecl = nil;
procedure TfrmMain.Button1Click(Sender: TObject);
var
DLLHandle: THandle;
dfuList: pdfuDeviceInfo;
getDfuListNb: Integer;
begin
DLLHandle := LoadLibrary('THE.DLL');
if DLLHandle = 0 then RaiseLastOSError;
try
getDfuDeviceList := GetProcAddress(DLLHandle, 'getDfuDeviceList');
if not Assigned(getDfuDeviceList) then RaiseLastOSError;
dfuList := nil;
getDfuListNb := getDfuDeviceList(dfuList, $DF11, $0483);
try
// Используйте dfuList и getDfuListNb по мере необходимости...
finally
// Освободите dfuList в соответствии с требованиями DLL,
// если это необходимо, используя функцию, экспортируемую DLL,
// или напрямую через функции операционной системы, если память
// была выделена функцией операционной системы.
end;
finally
FreeLibrary(DLLHandle);
end;
end;
Заключение:
Ошибка ACCESS_VIOLATION обычно возникает из-за несоответствия между тем, как программа ожидает использовать память, и тем, как память фактически выделена. В данном случае, проблема была вызвана неправильным управлением памятью и освобождением библиотеки до выполнения функций. Исправление этих ошибок позволит успешно вызвать функцию из 64-битной DLL в Delphi.
Пользователь столкнулся с проблемой, связанной с вызовом функции из 64-битной динамически подключаемой библиотеки в среде разработки Delphi, которая приводит к исключению `ACCESS_VIOLATION` из-за неправильного управления памятью и освобождения библиотеки
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.