Как правильно передать UDT из Delphi в VB6 через COM: решение проблемы с EOleException
Описание проблемы:
Вы столкнулись с проблемой при попытке передать пользовательский тип данных (UDT), определенный в Delphi, в метод VB6 DLL. В вашем Delphi приложении вы создали структуру TMyResults, соответствующую структуре MyResults в VB6 DLL, но при вызове метода Method1 из VB6 DLL через COM получаете ошибку EOleException из-за несоответствия типов.
Оригинальный код на Delphi:
TMyResults = packed record
Result1: Double;
Result2: Double;
Result3: Double;
Result4: Double;
Result5: Double;
end;
procedure TMyApp.CallMethod1FromVBDLL(var MyResults: TMyResults);
var
results: OleVariant;
dll: Variant;
begin
results := RecToVariant(MyResults, SizeOf(MyResults));
dll := CreateOleObject('ApplicationName.ClassName');
dll.Method1(results);
...
end;
function TMyApp.RecToVariant(var AR; ARecSize: Integer): Variant;
var
p: Pointer;
begin
Result := VarArrayCreate([1, ARecSize], varByte);
p := VarArrayLock(Result);
try
Move(AR, p^, ARecSize);
finally
VarArrayUnLock(Result);
end;
end;
Проблема:
Приведенный выше код создает OleVariant, который содержит байтовый массив, а VB6 ожидает UDT (Automation type VT_RECORD).
Решение:
Чтобы корректно передать UDT из Delphi в VB6, необходимо создать объект, реализующий интерфейс IRecordInfo, который будет оборачивать ваши данные UDT. Это позволит создать OleVariant типа VT_RECORD, что необходимо для COM и VB6 для правильной обработки данных.
Шаги для решения проблемы:
1. Создайте класс в Delphi, который реализует интерфейс IRecordInfo.
2. В этом классе оберните данные UDT и предоставьте информацию о типе данных.
3. Используйте созданный класс для создания OleVariant типа VT_RECORD, который затем можно передать в метод VB6 DLL.
Важно:
Вы также можете получить экземпляр IRecordInfo из типобibliотек, что может быть проще и надежнее, чем реализация интерфейса самостоятельно.
Пример реализации IRecordInfo в Delphi (псевдокод):
type
TMyRecordInfo = class(TInterfacedObject, IRecordInfo)
public
// Реализация методов IRecordInfo
end;
function TMyApp.CreateRecordVariant(const ARecord: TMyResults): OleVariant;
var
RecordInfo: IRecordInfo;
begin
RecordInfo := TMyRecordInfo.Create(ARecord);
Result := OleVariant.CreateRecord(RecordInfo);
end;
Использование в вашем коде:
procedure TMyApp.CallMethod1FromVBDLL(var MyResults: TMyResults);
var
results: OleVariant;
dll: Variant;
begin
results := CreateRecordVariant(MyResults);
dll := CreateOleObject('ApplicationName.ClassName');
dll.Method1(results);
...
end;
Заключение:
Следуя этим шагам, вы сможете правильно передать данные UDT из Delphi в VB6 через COM, избежав ошибки EOleException.
Проблема заключается в некорректной передаче пользовательского типа данных (UDT) из Delphi в VB6 через COM из-за различия в ожидаемых типах данных между двумя языками программирования.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.