Интеграция программного обеспечения с устаревшим оборудованием может привести к ряду проблем, особенно когда документация по DLL выполнена в Delphi. Одной из таких проблем является ошибка System.AccessViolationException, которая указывает на попытку чтения или записи защищенной памяти. Это часто является признаком того, что другая память повреждена, и может быть вызвана несоответствием типов данных и соглашений о вызовах между C# и Delphi.
Описание проблемы
Пользователь столкнулся с проблемой при интеграции своего программного обеспечения с оборудованием через DLL, созданную в Delphi. Функция ConfigurarOnLine в DLL ожидает параметры определенных типов, включая TObject, что не является безопасным для интероперабельности. Использование TObject в качестве параметра приводит к проблемам, так как структура TObject может отличаться в разных версиях Delphi, и нет прямого соответствия между TObject в Delphi и object в C#.
Подтвержденный ответ
Для решения проблемы необходимо создать прокси-библиотеку в Delphi, которая будет использовать безопасные для интероперабельности типы, такие как интерфейсы. Прокси-библиотека должна быть написана в той же или очень близкой версии компилятора Delphi, которая использовалась для создания исходной DLL. Это обеспечит совместимость структур данных и соглашений о вызовах.
Пример кода прокси-библиотеки
type
INotifyOnLine = interface
['{01234567-89AB-CDEF-0123-456789ABCDEF}']
procedure Execute(Numero: PChar; Tipo, Funcao, Relogio: Byte);
end;
INotifyError = interface
['{01234567-89AB-CDEF-0123-456789ABEFGH}']
procedure Execute(Erro, Versao: Byte);
end;
INotify = interface
['{01234567-89AB-CDEF-0123-456789ABFCD}']
end;
INotifyRegOff = interface
['{01234567-89AB-CDEF-0123-456789ABCDE}']
procedure Execute(RelNum: Byte);
end;
IConfigurarOnLine = interface
['{01234567-89AB-CDEF-0123-456789ABGHJ}']
function Execute(Sender: IInterface; Com: Byte; Velocidade: Word;
EvTrata: INotifyOnLine; EvGrava: INotify;
EvError: INotifyError; EvRegOff: INotifyRegOff): Boolean;
end;
{ TProxyConfigurarOnLine }
type
TProxyConfigurarOnLine = class(TInterfacedObject, IConfigurarOnLine)
private
function Execute(Sender: IInterface; Com: Byte; Velocidade: Word;
EvTrata: INotifyOnLine; EvGrava: INotify;
EvError: INotifyError; EvRegOff: INotifyRegOff): Boolean; stdcall;
end;
{ TDelegateWrapper }
type
TDelegateWrapper = class
private
FD: TNotifyEvent;
function GetInterface: INotify; stdcall;
public
constructor Create(const ADelegate: TNotifyEvent);
destructor Destroy; override;
end;
{ TProxyNotify }
type
TProxyNotify = class(TInterfacedObject, INotify)
private
FD: TNotifyEvent;
function GetInterface: INotify; stdcall;
public
constructor Create(const ADelegate: TNotifyEvent);
destructor Destroy; override;
end;
{ TProxyNotifyOnLine }
type
TProxyNotifyOnLine = class(TInterfacedObject, INotifyOnLine)
private
FD: TNotifyOnLineEvent;
function GetInterface: INotifyOnLine; stdcall;
public
constructor Create(const ADelegate: TNotifyOnLineEvent);
destructor Destroy; override;
end;
{ TProxyNotifyError }
type
TProxyNotifyError = class(TInterfacedObject, INotifyError)
private
FD: TNotifyErrorEvent;
function GetInterface: INotifyError; stdcall;
public
constructor Create(const ADelegate: TNotifyErrorEvent);
destructor Destroy; override;
end;
{ TProxyNotifyRegOff }
type
TProxyNotifyRegOff = class(TInterfacedObject, INotifyRegOff)
private
FD: TNotifyRegOffEvent;
function GetInterface: INotifyRegOff; stdcall;
public
constructor Create(const ADelegate: TNotifyRegOffEvent);
destructor Destroy; override;
end;
// Реализация методов создания оберток для делегатов и реализация интерфейсов
// ...
// Использование прокси-библиотеки в C# приложении
// ...
Альтернативный ответ
Если создание прокси-библиотеки невозможно или нежелательно, можно рассмотреть другие варианты, такие как использование временного файла с JSON-структурой для передачи данных между приложением и отдельным EXE, который будет обрабатывать вызов DLL.
Заключение
При работе с интероперабельностью между C# и Delphi важно использовать типы данных и соглашения о вызовах, которые обеспечивают совместимость и безопасность. Создание прокси-библиотеки является одним из способов решения проблемы, но требует тщательного планирования и разработки.
Пользователь столкнулся с проблемами при интеграции программного обеспечения, использующего C#, с устаревшим оборудованием через DLL, созданную в Delphi, и пытается устранить ошибки доступа к памяти, связанные с несоответствием типов данных и соглашений
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.