Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   DLL mehrere Strings auslesen (https://www.delphipraxis.net/130911-dll-mehrere-strings-auslesen.html)

S4SH1981 15. Mär 2009 16:54


DLL mehrere Strings auslesen
 
Hallo zusammen,

habe mal wieder :wall: ein Problem mit meiner DLL Datei.
Meine DLL soll mir die Netzwerkadapter auslesen.
Das tut sie soweit auch.
Nur das Problem ist, dass ich 4 Netzwerkadapter in meinem Rechner habe:
W-LAN
LAN
Bluetooth
FireWire

Meine DLL sieht so aus:
Delphi-Quellcode:
library GetNetworkAdapters;

{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der
  ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt-
  Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die
  Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle
  Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die
  sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur
  Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL.
  Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String-
  Informationen als PChar- oder ShortString-Parameter übergeben. }
 

uses
  sharemem,
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  ExtCtrls,
  StdCtrls,
  Winsock,
  IpRtrMib,
  IpHlpApi,
  IpTypes,
  IpIfConst;

{$R *.res}

function GetNetworkAdapter: string;
var
  MibRow: TMibIfRow;
  IntfTable: PMibIfTable;
  Size: DWORD;
  I: Integer;
begin
  Size := 0;
  If GetIfTable(nil, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
  IntfTable := AllocMem(Size);
  Try
    If GetIfTable(IntfTable, Size, True) = NO_ERROR then
      For I := 0 to IntfTable^.dwNumEntries -1 do
        begin
          {$R-}
          MibRow := IntfTable.Table[I];
          result := (PChar(@MibRow.bDescr[0]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s'
            );
          {$R+}
        end;
  Finally
    FreeMem(IntfTable);
  end;
end;

exports
   GetNetworkAdapter;

begin
end.
Wie bekomme ich nun in meinem Programm alle Adapter in einer z.B. Combobox angezeigt?
Bisher nutze ich
Delphi-Quellcode:
ComboBox1.Items.Add(getnetworkadapter);
und es wird mir nur ein beliebiger Adapter gezeigt.

quendolineDD 15. Mär 2009 16:58

Re: DLL mehrere Strings auslesen
 
Ein Array of String zurückgeben?

S4SH1981 15. Mär 2009 17:33

Re: DLL mehrere Strings auslesen
 
Und wie?

Versteh das gerade nicht so wirklich!

Luckie 15. Mär 2009 19:30

Re: DLL mehrere Strings auslesen
 
Über eien Callback-Funktion.

Apollonius 15. Mär 2009 19:35

Re: DLL mehrere Strings auslesen
 
Warum nicht einfach direkt ein Array of Strings zurückgeben?

S4SH1981 19. Mär 2009 14:34

Re: DLL mehrere Strings auslesen
 
Hallo

habe jetzt meine DLL auf die ganz einfache Weise mit dem Array of string erweitert.
Delphi-Quellcode:
          adapter[1] :=(PChar(@MibRow.bDescr[0]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[2] :=(PChar(@MibRow.bDescr[1]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[3] :=(PChar(@MibRow.bDescr[2]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[4] :=(PChar(@MibRow.bDescr[3]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[5] :=(PChar(@MibRow.bDescr[4]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
Wie stelle ich es nun an, dass alle Adapter in einer Comobobox aufgelistet werden.

sharemem habe ich da wo es stehen muss/soll eingetragen.

Bei dem Befehl
Delphi-Quellcode:
getnetworkadapter;
combobox1.Items.add(adapter[1]);
erhalten ich wieder eine Fehlermeldung.

Wo liegt denn der Fehler?

DP-Maintenance 19. Mär 2009 15:11

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage

quendolineDD 19. Mär 2009 15:13

Re: DLL mehrere Strings auslesen
 
Was für eine Fehlermeldung erhälst du denn? :glaskugel:

S4SH1981 19. Mär 2009 15:15

Re: DLL mehrere Strings auslesen
 
Zugriffsverletzung bei Adresse 00455CC43 in Modul Project1.exe Lesen von Adresse 00000004
Wähle ich Adapter[5] kommt das selbe nur mit 00000014

quendolineDD 19. Mär 2009 15:21

Re: DLL mehrere Strings auslesen
 
Hast du jetzt einen dynamisches Array (Array of String) oder ein statisches Array (Array[1..5] of String)?
Bei ersterem solltest du dir erst den Speicher für das Array allokieren, das amchst du mit SetLength(array, länge); Jedoch ist dann der erste Index 0 und der letzte ist länge -1.

S4SH1981 19. Mär 2009 15:53

Re: DLL mehrere Strings auslesen
 
Also hier die DLL

Delphi-Quellcode:
function GetNetworkAdapter: string;
var
  MibRow: TMibIfRow;
  IntfTable: PMibIfTable;
  Size: DWORD;
  I: Integer;
  Adapter : array[1..5] of string;
begin
  Size := 0;
  If GetIfTable(nil, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
  IntfTable := AllocMem(Size);
  Try
    If GetIfTable(IntfTable, Size, True) = NO_ERROR then
      For I := 0 to IntfTable^.dwNumEntries -1 do
        begin
          {$R-}
          MibRow := IntfTable.Table[I];
          adapter[1] :=(PChar(@MibRow.bDescr[0]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[2] :=(PChar(@MibRow.bDescr[1]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[3] :=(PChar(@MibRow.bDescr[2]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[4] :=(PChar(@MibRow.bDescr[3]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
          adapter[5] :=(PChar(@MibRow.bDescr[4]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');

          result := (PChar(@MibRow.bDescr[0]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s'
            );
          {$R+}
        end;
  Finally
    FreeMem(IntfTable);
  end;
end;

exports
   GetNetworkAdapter;

begin
end.
und das Programm

Delphi-Quellcode:
function GetNetworkAdapter : string;
external 'C:\Dokumente und Einstellungen\Bettina & Detlef\Desktop\Delphi\11032009\DLL4\GetNetworkAdapters.dll';

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
var adapter : array of string;
begin
// ComboBox1.Items.Add(getnetworkadapter);
getnetworkadapter;
//combobox1.Items.add(adapter[1]);

end;

S4SH1981 20. Mär 2009 13:03

Re: DLL mehrere Strings auslesen
 
*** push ***

cruiser 20. Mär 2009 13:58

Re: DLL mehrere Strings auslesen
 
Mein Vorschlag wäre ja das ganze aufzusplitten:

in der DLL zwei Funktionen:

Delphi-Quellcode:
function GetNetworkAdapterCount: integer;

function GetNetworkAdapter(index: integer; buffer: PChar; size: integer): integer;
Der Aufruf müsste dann nach folgendem Schema erfolgen (Pseudocode):

Code:
ac = GetNetworkAdapterCount;
for i = 0 to ac - 1
begin
  size = GetNetworkAdapter(i, nil, 0);
  -> erstelle einen Buffer mit der Länge size
  GetNetworkAdapter(i, buffer, size);
  -> verwende Buffer weiter.. z.B. als String
     in eine Stringlist oder in ein Array
end;
GetNetworkAdapter wird also 2 mal pro Wert aufgerufen.

Im ersten Aufruf weiss die DLL durch buffer = nil dass sie die Länge des Strings zurückgeben muss.

Beim zweiten Aufruf kopiert sie den String aus der DLL in den Buffer der ja in der Anwendung selbst definiert ist. Wichtig ist das kopieren, denn wenn der Buffer in der DLL freigegeben wird, ist nicht sicher ob da wirklich noch daten drin sind.

Alternativ kannst du wie oben schon erwähnt auch callbacks einsetzen.

Apollonius 20. Mär 2009 14:02

Re: DLL mehrere Strings auslesen
 
Wenn du sowieso schon ShareMem verwendest, kannst du direkt ein array of String zurückgeben:
Delphi-Quellcode:
type TDynStringArray = array of String;

function GetNetworkAdapters: TDynStringArray;
begin
//...
end;

S4SH1981 20. Mär 2009 16:47

Re: DLL mehrere Strings auslesen
 
sorry aber ich schnall das nicht.

der soll mir per array of string die 4 adapter aus der dll in die combobox des programms schaufeln.

S4SH1981 20. Mär 2009 21:35

Re: DLL mehrere Strings auslesen
 
Habe mich jetzt stundenlang durch google und tutorials geklickt, aber wirklich schlauer bin ich nciht geworden.

meine dll funktioniert soweit perfekt.
ich kann mir die adaper schön per showmessage zeigen lassen.

Nur wie bekomme ich die in die combobox oder was auch immer in mein hauptprogramm.

Mit dem array of string verstehe ich das absolut nicht, bin da wohl zu blöd für.

Dank an alle die mir bisher schon geholfen haben.

S4SH1981 25. Mär 2009 19:14

Re: DLL mehrere Strings auslesen
 
Habe mich jetzt nochmal schlau gemacht, aber der Erfolg lässt weiter auf sich warten.
Mache es zurzeit so, dass ich in der DLL sagen muss welchen Adapter ich nun ansteuern will.

Delphi-Quellcode:
function GetNetworkAdapter(var J : integer) : string;
var
  MibRow: TMibIfRow;
  IntfTable: PMibIfTable;
  Size: DWORD;
  I : Integer;
begin
  Size := 0;
  If GetIfTable(nil, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
  IntfTable := AllocMem(Size);
  Try
    If GetIfTable(IntfTable, Size, True) = NO_ERROR then
//      For I := 0 to IntfTable^.dwNumEntries -1 do
[b]I := 0;[/b]
        begin
          MibRow := IntfTable.Table[I];
          result := (PChar(@MibRow.bDescr[0]) + ' @ ' + InttoStr(MibRow.dwSpeed div 1000000)+ ' MBit/s');
        end;
  Finally
    FreeMem(IntfTable);
  end;
end;

exports
   GetNetworkAdapter;

begin
end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz