Autor Beitrag
ASMFreak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 53
Erhaltene Danke: 9



BeitragVerfasst: Mo 30.01.12 14:00 
Hallo, liebe Community,

manchmal wünsche ich mir die guten, alten Pointer zurück!

Ich habe ein Problem, mit dem ich noch keine Erfahjrung habe, da ich bislang entweder im unmanaged code herumgewerkelt habe, ODER im managed. Jetzt habe ich aber ein Problem, das beides betrifft.

Ich benötige Informationen aus unmanaged code in Form einer Liste von GUIDs. Um die zu ermitteln, gibt es eine Schnittstellenfunktion, die wie folgt deklariert ist:
ausblenden C#-Quelltext
1:
2:
3:
4:
HRESULT GetIds(
  [out]      GUID **ppId,
  [inout]  UINT *pCount
);

Die versuche ich, mit Delphi anzusprechen. Daher habe ich einen Delegaten deklariert nach
ausblenden Delphi-Quelltext
1:
funktion GetIDs(out pKD: KommtGleich; out Count: Integer): HResult					

Das Natürliche wäre nun, eine Variable
ausblenden Delphi-Quelltext
1:
2:
3:
4:
type
  TGUIDArray = Array of TGUID;
var
  GUIDArray: TGUIDArray

zu deklarieren und der Funktion zu übergeben. Tut man das, erhält man die Exception "Es wurde ein SafeArray vom Rang 14852 an eine Methode übergeben, die ein Array vom Rang 1 erwartet hat." OK! Das ist dar Problem der Datenübertragung zwischen unmanaged und managed code, wie ich vermute. Also: marshallen. Aber: wie? Meine diversen Versuche haben nichts gebracht.

Also zweiter Versuch:
ausblenden Delphi-Quelltext
1:
function GetIDs(out pKD: IntPtr; out Count: Integer): HResult;					

Und der Vesuch, analog zur damaligen Zuweisung eines PGUIDArray an eine Variable das Problem zu lösen. Aber auch hier führten meine Versuche des Marshallens nicht zum Erfolg. Entweder, der zurückgegebene Pointer erzeugte eine Exception nach dem Motto: "Es wurde versucht, in geschütztem Code zu lesen oder zu schreiben" oder so ähnlich, oder der Versuch, dass array auszulesen, wurde mit der Meldung bestraft, dass der Index den erlaubten Bereich überschreitet - auch beim Index 0 und obwohl mir Count sehr glaubhaft mitteilt, dass es jede Menge Einträge in der Liste gibt.

Kann mir jemand helfen?

Gruß,
ASMFreak

_________________
Und aus dem Chaos sprach eine Stimme zu mir: Lächle und sei froh, es könnte schlimmer kommen.
Und ich lächelte und ich war froh – und es kam schlimmer!
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 432
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Mo 30.01.12 14:52 
auch wenn meine c-zeiten lange zurückliegen, wie wäre es mit:


ausblenden Delphi-Quelltext
1:
2:
3:
4:
type
  TGUIDArray = Array [0..10000of TGUID;

funktion GetIDs(var pKD: TGUIDArray; var Count: Integer): HResult


der Unterschied array of und array [0 .. 10000] of:
bei ersterem "bastelt" der Compiler noch etliches herum um mit diesem dynamischen Array arbeiten zu können damit auch Funktionen wie setlength etc. funktionieren.

Durch die var-Definition der Variablen übergibt der Compiler beim Funktionsaufruf nur die Adresse der Variablen an die aufgerufene Funktion, was diese damit macht und evtl. dort Werte änert ist ihm dann egal.

Die Grenze 10000 habe ich willkürlich gewählt.
ASMFreak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 53
Erhaltene Danke: 9



BeitragVerfasst: Mo 30.01.12 15:09 
Habe ich vergessen zu sagen: Natürlich habe ich es auch damit versucht: Mit dem gleichen Ergebnis. Es schient kein Problem des "Herumbastelns" beim dynamischen Array zu sein, sondern ein Problem, an strukturierte Daten aus einem unmanaged code-Bereich zu kommen.

_________________
Und aus dem Chaos sprach eine Stimme zu mir: Lächle und sei froh, es könnte schlimmer kommen.
Und ich lächelte und ich war froh – und es kam schlimmer!
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 432
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Mo 30.01.12 15:19 
Hast Du die Funktion als stdcall definiert? liegt sie evtl. sogar in einer DLL?
ASMFreak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 53
Erhaltene Danke: 9



BeitragVerfasst: Mo 30.01.12 15:58 
Nein, sie ist Teil einer Schnittstellendefinition. Wenn ich da mit "stdcall" ran gehe, meckert der Compiler, dass das bei externen Deklarationen nicht erlaubt sei!

Das Ganze sieht wie folgt aus (ich kopiere jetzt nicht die ganze Unit, daher nur das Prinzip):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
unit Test;

interface

type
  [ComImport,
  GuidAttribute ...
  ISchnittstelle = interface
    :
    :
    [PreserveSig]
    function GetIDs(out ppkFID: TGUIDArray; var Count: Integer): HResult;
    :
    :
  end;


später wird dann eine Klasse definiert, in der dann steht:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
type
  EineKlasse = class(TObject)
    :
  public
    :
    procedure GetTheIDs(Ifc: ISchnittstelle);
    :
  end;


Und im Implementationsteil folgt dann

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure EineKlasse.GetTheIDs(Ifc: ISchnittstelle);
  var
    IDs: TGUIDArray;
    Count: Integer;
begin
  OleCheck(Ifc.GetIDs(IDs, Count));
end;


Das funktioniert mit allen anderen Methoden der Schnittstelle hervorragend, nur diese zickt rum. Zugegeben: Alle anderen Methdoen haben auch "einfache" Daten wie Strings oder Uints. Diese hier hat strukturierte Daten (Array). Und, wie gesagt, es ist egal, ob TGUIDArray = Array of TGUID oder TGUIDList = Array[0..irgendwas] of TGUID.

_________________
Und aus dem Chaos sprach eine Stimme zu mir: Lächle und sei froh, es könnte schlimmer kommen.
Und ich lächelte und ich war froh – und es kam schlimmer!
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 432
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Mo 30.01.12 17:04 
Da muß ich leider passen, evtl. würde das Debug/CPU-Fenster weiterhelfen?
ASMFreak Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 53
Erhaltene Danke: 9



BeitragVerfasst: Mo 30.01.12 17:11 
Nicht wirklch! Danke trotzdem!

_________________
Und aus dem Chaos sprach eine Stimme zu mir: Lächle und sei froh, es könnte schlimmer kommen.
Und ich lächelte und ich war froh – und es kam schlimmer!