AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Wie ein array of record von C# dll mit COM an Delphi übergeben?
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von jus · begonnen am 26. Mai 2023 · letzter Beitrag vom 9. Jul 2023
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#11

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

  Alt 28. Mai 2023, 14:13
Besonders die Attribute wie [Marshal...] und [LPArray...] usw., wo stehen diese Sachen eigentlich in der Doku drin?
Zum Beispiel hier:
UnmanagedType Enumeration Referenz

Viel Material gibt es dazu aber wirklich nicht. Zum Beispiel musste ich auch erst herausfinden, dass man dabei ein paar Einschränkungen hat was Rückgabewerte usw. angeht.

Das größte Problem ist aber das Debugging. Visual Studio unterstützt bei solchen DLLs leider keinerlei Debugging, so dass man von Anfang an ein gutes Logging einbauen sollte.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (28. Mai 2023 um 14:15 Uhr)
  Mit Zitat antworten Zitat
jus

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

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

  Alt 2. Jun 2023, 21:31
- Klassenbibliothek (.NET Framework) erstellen
- In den Projekteigenschaften unter Build --> Allgemein das Plattformziel auf x86 setzen
- Bezeichnungen der Klassen / Namespace usw. setzen
- DllExport installieren
--> Es öffnet sich dieses Fenster:
Anhang 56072
Dort das Häkchen bei "Installed" setzen wie im Screenshot zu sehen und Apply drücken! Der Namespace sollte automatisch passen, wenn es ein neues Projekt ist, aber den kann man dort ggf. auch anpassen.

Dann auf Aufforderung des Visual Studios die Mappe neu laden (weil die Projektdatei extern geändert wurde).

Nun sollte DllExport gefunden werden.
ja, ok habe nun ausprobiert, es war tatsächlich nur das installed Häkchen, das gefehlt hat.

@jaenicke: Bei Übergabe von array of record/struct zwischen Delphiprogramm und einer Delphi DLL kann man natürlich locker ein array of record im Parameter übergeben. Zwischen Delphiprogramm und C DLL soll ja am besten nur den Zeiger auf den 1.Record vom Array geben und die Arrayanzahl. Aber wie kann man ein array of record/struct mit IInterface zwischen Delphiprogramm und C# übergeben? Wäre es dann eine InterfaceList statt einem Array?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#13

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

  Alt 3. Jun 2023, 02:44
Du kannst natürlich das Array auch als Parameter einer Funktion des Interfaces übergeben. Ich persönlich nutze allerdings lieber eine Interface-Liste.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
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
jus

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

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

  Alt 8. Jun 2023, 20:57
ok, bin jetzt einen kleinen Schritt weiter. Meine Vermutung ist, dass die Referenzzählung in Verbindung mit der C# DLL bei mir Probleme macht. Darum wäre meine Quick&Dirty Lösung, dass ich direkt beim Beenden der Methode in den Referenzzähler reinpfusche:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  TransportList: ITransportListIntf;
  MediaList: TMediaArray;
  i, j: Integer;
begin
  TransportList := TTransportList.Create;
  try
    getMediaList( TransportList ); // <--- hier wird die C# DLL Methode aufgerufen
    TransportList.getList( MediaList );
  finally
    if TransportList <> nil then
    begin
      j := TransportList._AddRef;
      for i := j downto 2 do TransportList._Release; //<----- setze manuell den Referenzzähler
    end;
  end;
end;
Damit gibt es nun keine Meldung von Fastmm, dass es einen Speicherleck gibt. Meine Frage an die Experten: Ist es total verwerflich, was ich da mache? Und gibt es da einen besseren Weg?

Geändert von jus ( 8. Jun 2023 um 21:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#16

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

  Alt 9. Jun 2023, 02:05
Hast du denn mal _Addref und _Release selbst implementiert und einen Haltepunkt drauf gesetzt? Dann sollte doch klar werden, wo die zusätzliche Referenz herkommt.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#17

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

  Alt 14. Jun 2023, 14:52
Ich habe nun die angesprochene Funktionalität in neu geschriebener Form veröffentlicht:
https://www.delphipraxis.net/213199-...ng-dlls-c.html
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
jus

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

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

  Alt 14. Jun 2023, 20:53
vielen vielen Dank!! Das muß ich mir mal in Ruhe anschauen
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#19

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

  Alt 7. Jul 2023, 10:37
Das ist im Grunde das gleiche, auch von der Verwendung her. DllExport ist neuer, das Unmanaged Exports wird schon länger nicht mehr gepflegt, weshalb ich für neue Projekte das neuere empfehlen würde. Außerdem ist das durch den Wizard für die Projektkonfiguration sogar noch einfacher.
Ja, bitte nutzt das neuere.
Ich habe vor weit über 10 Jahren aufgegeben, mit jeder neuen Version von msbuild oder .Net den Code anpassen zu müssen, der ildasm/ilasm findet.
War mir damals zu heikel es mit Mono.Cecil oder IKVM.Reflection zu machen.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#20

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

  Alt 7. Jul 2023, 13:14
Vielen Dank für deine Antwort.

Mit neueren Versionen als .NET 4.8 habe ich allerdings auch mit der neueren Version noch ein paar Meinungsverschiedenheiten. Den Quelltext habe ich ja veröffentlicht. Wenn ich das mit .NET 6.0 oder so versuche, knallt es. Ich bin noch nicht dazu gekommen, mir das anzuschauen. Erst einmal muss ich noch die Anleitung fertig schreiben und dann habe ich noch ein paar andere Todos in dem Projekt.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz