метод com-объекта не возвращает packed record

evgen29
Дата: 10.06.2019 14:21:07
Здравствуйте!
Создал com-объект, один из методов Item должен возвращать packed record.
при вызове метода в ранее созданном объекте
mycomobject.GetCerts.Item(1).Name

возникает ошибка
Invalid variant operation

хотя к примеру метод mycomobject.GetCerts.Count нормально работает. т.е. дело в неправильной реализации метода.

код:
  TCertificate = packed record
    Name: WideString;
    StartDate: WideString;
    EndDate: WideString;
    Stamp: WideString;
  end;

...

function TCertificates.Item(i: Integer): TCertificate;
var
  C: TCertificate;
begin
  C.Name:='';
  C.StartDate:='';
  C.EndDate:='';
  C.Stamp:='';
  result:=C;
end;


что я делаю не так?
_Vasilisk_
Дата: 10.06.2019 14:59:28
Для начала покажите idl. Потом как эта tlb проимпортировалась в pas и само описание класса реализации,

Далее, это настоящий COM? Т.е. вы создаете объект через CreateComObject или простой интерфейс?
evgen29
Дата: 10.06.2019 15:49:54
_Vasilisk_,

я вызываю ком-объект из клиента по имени
mdlp := CreateOleObject('MyComObj.MyComObjC');
_Vasilisk_
Дата: 10.06.2019 15:53:48
Еще и OLE. Не будет так работать.

Давайте так
_Vasilisk_
Для начала покажите idl.
а дальше будем рихтовать
evgen29
Дата: 10.06.2019 16:21:41
_Vasilisk_
Еще и OLE. Не будет так работать.

Давайте так
_Vasilisk_
Для начала покажите idl.
а дальше будем рихтовать


[
  uuid(E038B7F4-BDD3-4A74-BEAF-F97FB95262DF),
  version(1.0),
  helpstring("MyComObj Library")

]
library MyComObj
{

  importlib("stdole2.tlb");

  [
    uuid(25DBA330-010B-4776-8807-F8181BF0C362),
    version(1.0),
    helpstring("MyComObjC Object")
  ]
  coclass MyComObjC
  {
    [default] interface IMyComObjC;
  };

  [
    uuid(37F55512-75B4-44F8-A49D-4D97BA760EBB),
    version(1.0)
  ]
  coclass Certificates
  {
    [default] interface ICertificates;
  };

  [
    uuid(4C51E6A1-C632-4C05-8529-08646EABB560),
    version(1.0)
  ]
  typedef struct tagTCertificate
  {
    BSTR Name;
    BSTR StartDate;
    BSTR EndDate;
    BSTR Stamp;
  } TCertificate;

  [
    uuid(3A1292A9-FD00-4679-A0A0-4C6D4810B49C),
    version(1.0),
    helpstring("Dispatch interface for MyComObjC Object"),
    dual,
    oleautomation
  ]
   interface IMyComObjC: IDispatch
  {
    [
    id(0x000000C9)
    ]
    HRESULT _stdcall GetCerts([out, retval] ICertificates ** GetCerts /*Warning: unable to validate structure name: */ );
    [
  };

  [
    uuid(2A5BE8DA-B486-44D5-8533-238D60AB5535),
    version(1.0),
    dual,
    oleautomation
  ]
   interface ICertificates: IDispatch
  {
    [
    id(0x000000C9)
    ]
    HRESULT _stdcall Item([in] long i, [out, retval] TCertificate * Item /*Warning: unable to validate structure name: */ );
    [
    id(0x000000CA)
    ]
    HRESULT _stdcall Count([out, retval] VARIANT * Count );
  };

};
evgen29
Дата: 10.06.2019 16:24:31
убрал лишнее

type
  TMyComObj = class(TAutoObject, IMyComObj)
  protected
    function GetCerts: ICertificates; safecall;
  end;

  TCertificates = class(TAutoObject, ICertificates)
  protected
    function Count: OleVariant; safecall;
    function Item(i: Integer): TCertificate; safecall;
  end;


...


initialization
  TAutoObjectFactory.Create(ComServer, TMyComObj, Class_MyComObjC,
    ciMultiInstance, tmApartment);
  TAutoObjectFactory.Create(ComServer, TCertificates, CLASS_Certificates,
    ciMultiInstance, tmApartment);
evgen29
Дата: 10.06.2019 16:36:09
_tlb.pas
unit MyComObj_TLB;
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers. 
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
  

// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:        
//   Type Libraries     : LIBID_xxxx                                      
//   CoClasses          : CLASS_xxxx                                      
//   DISPInterfaces     : DIID_xxxx                                       
//   Non-DISP interfaces: IID_xxxx                                        
// *********************************************************************//
const
  // TypeLibrary Major and minor versions
  MyComObjMajorVersion = 1;
  MyComObjMinorVersion = 0;

  LIBID_MyComObj: TGUID = '{E038B7F4-BDD3-4A74-BEAF-F97FB95262DF}';

  IID_IMyComObjC: TGUID = '{3A1292A9-FD00-4679-A0A0-4C6D4810B49C}';
  CLASS_MyComObjC: TGUID = '{25DBA330-010B-4776-8807-F8181BF0C362}';
  IID_ICertificates: TGUID = '{2A5BE8DA-B486-44D5-8533-238D60AB5535}';
  CLASS_Certificates: TGUID = '{37F55512-75B4-44F8-A49D-4D97BA760EBB}';
type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary                    
// *********************************************************************//
  IMyComObjC = interface;
  IMyComObjCDisp = dispinterface;
  ICertificates = interface;
  ICertificatesDisp = dispinterface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library                       
// (NOTE: Here we map each CoClass to its Default Interface)              
// *********************************************************************//
  MyComObjC = IMyComObjC;
  Certificates = ICertificates;


// *********************************************************************//
// Declaration of structures, unions and aliases.                         
// *********************************************************************//
  TCertificate = packed record
    Name: WideString;
    StartDate: WideString;
    EndDate: WideString;
    Stamp: WideString;
  end;


// *********************************************************************//
// Interface: IMyComObjC
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {3A1292A9-FD00-4679-A0A0-4C6D4810B49C}
// *********************************************************************//
  IMyComObjC = interface(IDispatch)
    ['{3A1292A9-FD00-4679-A0A0-4C6D4810B49C}']
    function GetCerts: ICertificates; safecall;
  end;

// *********************************************************************//
// DispIntf:  IMyComObjCDisp
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {3A1292A9-FD00-4679-A0A0-4C6D4810B49C}
// *********************************************************************//
  IMyComObjCDisp = dispinterface
    ['{3A1292A9-FD00-4679-A0A0-4C6D4810B49C}']
    function GetCerts: ICertificates; dispid 201;
  end;

// *********************************************************************//
// Interface: ICertificates
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {2A5BE8DA-B486-44D5-8533-238D60AB5535}
// *********************************************************************//
  ICertificates = interface(IDispatch)
    ['{2A5BE8DA-B486-44D5-8533-238D60AB5535}']
    function Item(i: Integer): TCertificate; safecall;
    function Count: OleVariant; safecall;
  end;

// *********************************************************************//
// DispIntf:  ICertificatesDisp
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {2A5BE8DA-B486-44D5-8533-238D60AB5535}
// *********************************************************************//
  ICertificatesDisp = dispinterface
    ['{2A5BE8DA-B486-44D5-8533-238D60AB5535}']
    function Item(i: Integer): {??TCertificate}OleVariant; dispid 201;
    function Count: OleVariant; dispid 202;
  end;

// *********************************************************************//
// The Class CoMyComObjC provides a Create and CreateRemote method to          
// create instances of the default interface IMyComObjC exposed by              
// the CoClass MyComObjC. The functions are intended to be used by             
// clients wishing to automate the CoClass objects exposed by the         
// server of this typelibrary.                                            
// *********************************************************************//
  CoMyComObjC = class
    class function Create: IMyComObjC;
    class function CreateRemote(const MachineName: string): IMyComObjC;
  end;

// *********************************************************************//
// The Class CoCertificates provides a Create and CreateRemote method to          
// create instances of the default interface ICertificates exposed by              
// the CoClass Certificates. The functions are intended to be used by             
// clients wishing to automate the CoClass objects exposed by the         
// server of this typelibrary.                                            
// *********************************************************************//
  CoCertificates = class
    class function Create: ICertificates;
    class function CreateRemote(const MachineName: string): ICertificates;
  end;

implementation

uses ComObj;

class function CoMyComObjC.Create: IMyComObjC;
begin
  Result := CreateComObject(CLASS_MyComObjC) as IMyComObjC;
end;

class function CoMyComObjC.CreateRemote(const MachineName: string): IMyComObjC;
begin
  Result := CreateRemoteComObject(MachineName, CLASS_MyComObjC) as IMyComObjC;
end;

class function CoCertificates.Create: ICertificates;
begin
  Result := CreateComObject(CLASS_Certificates) as ICertificates;
end;

class function CoCertificates.CreateRemote(const MachineName: string): ICertificates;
begin
  Result := CreateRemoteComObject(MachineName, CLASS_Certificates) as ICertificates;
end;

end.
Dimitry Sibiryakov
Дата: 10.06.2019 16:36:54

evgen29
Создал com-объект, один из методов Item должен возвращать packed record.

Во-первых, использовать packed (и вообще record) в СОМ - необычно.
Во-вторых, если уж используешь - все поля записи должны быть COM-совместимыми. То есть
исключительно OleString вместо WideString.
В-третьих, Дельфийские баги не позволяют методам интерфейса возвращать что-либо кроме
HRESULT, то есть одни должны быть объявлены как safecall. То есть объявление в первом
посте не соответствует ему в последнем.

Posted via ActualForum NNTP Server 1.5

evgen29
Дата: 10.06.2019 16:48:00
Dimitry Sibiryakov
evgen29
Создал com-объект, один из методов Item должен возвращать packed record.

Во-первых, использовать packed (и вообще record) в СОМ - необычно.
Во-вторых, если уж используешь - все поля записи должны быть COM-совместимыми. То есть
исключительно OleString вместо WideString.
В-третьих, Дельфийские баги не позволяют методам интерфейса возвращать что-либо кроме
HRESULT, то есть одни должны быть объявлены как safecall. То есть объявление в первом
посте не соответствует ему в последнем.


ну я создаю архитектуру объекта через пункт View->Type Library
Widestring вполне нормально обрабатывается, если я задаю его результатом функции-Метода с возвращаемым типом OleVariant;

но тут возвращаться должна packed record.
kealon(Ruslan)
Дата: 10.06.2019 17:18:28
evgen29
ну я создаю архитектуру объекта через пункт View->Type Library
Widestring вполне нормально обрабатывается, если я задаю его результатом функции-Метода с возвращаемым типом OleVariant;

но тут возвращаться должна packed record.
так его и задавай, вот только из скриптовых языков ты потом разрулить такой результат не сможешь