Einzelnen Beitrag anzeigen

jus

Registriert seit: 22. Jan 2005
344 Beiträge
 
Delphi 2007 Professional
 
#14

AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?

  Alt 7. Jun 2023, 21:39
@jaenicke: ich versuche einbisschen durch deinen Hinweis mit Interfaces zu experimentieren. Ich erstelle ein Interfaceobjekt in Delphi und übergebe es an die C# DLL Methode als Parameter.
Delphi-Quellcode:
type
  TMedia = record
    Name: WideString;
    ID: Integer;
  end;
  TMediaArray = array of TMedia;

  ITransportListIntf = interface
    ['{F059A4D4-1E57-4E4C-A300-5139F53E4062}']
    procedure Clear; safecall;
    procedure Add( Name: WideString; ID: Integer ); safecall;
    procedure getList( var items: TMediaArray ); safecall;
  end;

  TTransportList = class(TInterfacedObject, ITransportListIntf)
  private
    FData: TMediaArray;
  public
    procedure Clear; safecall;
    procedure Add( Name: WideString; ID: Integer ); safecall;
    procedure getList( var items: TMediaArray ); safecall;
  end;

implementation

uses Dialogs;

{ TTransportList }

procedure TTransportList.Add(Name: WideString; ID: Integer);
begin
  SetLength(FData, Length(FData) + 1);
  FData[High(FData)].Name := Name;
  FData[High(FData)].ID := ID;
end;

procedure TTransportList.Clear;
begin
  SetLength(FData,0);
end;

procedure TTransportList.getList(var items: TMediaArray);
begin
  items := FData;
end;

end.
Code:
        [Guid("F059A4D4-1E57-4E4C-A300-5139F53E4062"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface ITransportListIntf
        {
            void Clear();
            void Add([MarshalAs(UnmanagedType.BStr)] String Name, int ID);
            void getList(out RMEDIA[] items);
        }

        [DllExport]
        public static int getMediaList([In,Out, MarshalAs(UnmanagedType.Interface)] ITransportListIntf TransportList)
        {
            //...
            TransportList.Add( mediaName, mediaID );
            //....
        }
in Delphi wird es dann wie folgt gestartet:
Delphi-Quellcode:

type
  TgetMediaList = function ( MediaList: ITransportListIntf ): Integer; stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var
  TransportList: ITransportListIntf;
  MediaList: TMediaArray;
begin
  TransportList := TTransportList.Create;
  getMediaList( TransportList ); // <--- hier wird die C# DLL Methode aufgerufen
  TransportList.getList( MediaList );
end;
Grundsätzlich funktioniert es auch ohne Probleme. Jetzt habe ich aber festgestellt, dass es ein Speicherleck (Fastmm zeigt es beim Beenden an) produziert. Anscheinend wird TransportList Objekt nicht freigeben. Was muss man tun, damit es freigeben wird ?

Geändert von jus ( 7. Jun 2023 um 22:01 Uhr)
  Mit Zitat antworten Zitat