Autor Beitrag
Frolo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 02:15 
Hey,

ich arbeite derzeit für eine AG in der Schule an einer Software zum Ansteuern eines RoboTX Interfaces (Fischertechnik). Diese stellen eine Library zur Verfügung, doch mit einer der Funktionen habe ich so meine Probleme:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
2.13 EnumComPorts
DWORD EnumComPorts (DWORD idx,
LPSTR comstr,
DWORD maxlen)
Liefert einen Eintrag aus der von der Library erstellten statischen Liste der zur Verfügung
stehenden COM-Ports. Ein vorheriger Aufruf der Funktion "GetAvailableComPorts()" ist
notwendig. Der Eintrag wird als String mit Angabe des COM-Ports und einer Beschreibung
der Verwendung, wie sie aus der Windows-Registry zu entnehmen ist, zurückgegeben, z.B.:
"COM32 (fischertechnik USB ROBO TX Controller)". Der übergebene Stringbuffer muß
entsprechend dimensioniert sein, damit dieser den String mit der Beschreibung aufnehmen
kann.
Aufruf: DWORD idx - Listenindex innerhalb der Liste der verfügbaren COM-Ports
0 < idx < iComPorts (GetAvailableComPorts())
LPSTR comstr - Stringbuffer zur Aufnahme der COM-Beschreibung
DWORD maxLen - max. Länge des Stringbuffers
Return: DWORD index - Index des Listeneintrags welcher gelesen wurde (= idx),
im Fehlerfall wird der Wert FTLIB_ERR_INVALID_PARAM
zurückgegeben


Das sind bis jetzt meine Ansätze, die wohl ein richtiger Fail sind, weil ich von einem "Stringbuffer" nichts verstehe. Ich habe euch ja alles gegeben, was ich habe, bei mir wirft das eine Zugriffsverletzung aus (was euch bestimmt klar ist) für mich ist das halt logisch :D

Bei MaxLen habe ich einen mehr oder weniger zufälligen Wert genommen, was aus meiner Dummheit resultiert :D

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function Init(): DWORD; stdcallexternal 'ftMscLib.dll' name 'ftxInitLib';
function ComPorts(mode: Integer): DWORD; stdcallexternal 'ftMscLib.dll' name 'GetAvailableComPorts';
function EnumComPorts(idx: DWORD; comstr:String; maxlen: DWORD): DWORD; stdcallexternal 'ftMscLib.dll' name 'EnumComPorts';
//DWORD EnumComPorts (DWORD idx,LPSTR comstr,DWORD maxlen)

procedure TForm1.Button1Click(Sender: TObject);
var
  test: String;
begin
  Init();
  ShowMessage(IntToStr(ComPorts(1)));
  EnumComPorts(0,test,64);
  ShowMessage(test);
end;


Danke schonmal!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 02:35 
Versuch es mal so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
function EnumComPorts(idx: DWORD; comstr:PChar; maxlen: DWORD): DWORD; stdcallexternal 'ftMscLib.dll' name 'EnumComPorts';
//DWORD EnumComPorts (DWORD idx,LPSTR comstr,DWORD maxlen)

procedure TForm1.Button1Click(Sender: TObject);
const
  MAX_STRLEN = 1024;
var
  test: String;
begin
  Init();
  ShowMessage(IntToStr(ComPorts(1)));
  SetLength(test, MAX_STRLEN);
  EnumComPorts(0, PChar(test), Length(test));
  SetLength(test, StrLen(PChar(test)));
  ShowMessage(test);
end;

Beim C-Typ LPSTR bin ich gerade nicht sicher, ob das explizit Ansi ist. Falls ja, besser String in AnsiString und PChar in PAnsiChar ändern.

Für diesen Beitrag haben gedankt: Frolo
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 11:42 
Du bist ein Schatz. Aber ich musste PAnsiChar verwenden sonst kamen nur chinesische Schriftzeichen. Ich hab nur kleine Verständnisprobleme, weil ich mich mit den einzelnen Variablentypen noch nicht wirklich auseinander gesetzt habe :/
ausblenden Delphi-Quelltext
1:
SetLength(test, MAX_STRLEN);					

1. Wieso wird die Länge von "test" genau auf 1024 Zeichen gesetzt?
2. Warum muss man überhaupt PChar nehmen? Was ist der Unterschied zwischen PChar und String? Bzw PAnsiChar und AnsiString?
ausblenden Delphi-Quelltext
1:
SetLength(test, StrLen(PChar(test)));					

3. Verstehe ich leider kaum :/ Die Funktion StrLen ist mir quasi unbekannt. Wäre nett wenn du darauf weiter eingehen könntest


Aber schon einmal vielen dank :)


EDIT:// Hab Delphi 7 mal testweise installiert und habe ein Problem: Es funktioniert alles: Die Anzahl der ComPorts stimmt und auch die Ausgabe des COM-Ports als String geht, nur bekomme ich nach dem Schließen der letzten Messagebox das:

---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt D:\Users\Tobias\Downloads\TXInterface\TXInterface\Test.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0xf6190da2: read of address 0xf6190da2'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK
---------------------------

Ich kann mir das nicht erklären, weil danach ja im Grunde nichts mehr passiert o:
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 12:12 
Die 1024 ist willkürlich gesetzt. Zu den unterschiedlichen Typen verweise ich einfach auf den Hersteller, das ist mir zuviel zu Tippen. Bzgl. des Fehlers: bist Du sicher, dass er durch diese Routine ausgelöst wird? Oder kommt er auch, wenn diese gar nicht durchlaufen wird?

Für diesen Beitrag haben gedankt: Frolo
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 12:19 
Zu dem Fehler: Erstmal, mit Delphi XE3 kommt der Fehler nicht, beim kompilieren unter Delphi 7 aber schon. Der Fehler wird wohl durch die Funktion "ComPorts" ausgelöst, da der Fehler kommt, wenn alle anderen Zeilen auskommentiert sind. Diese Funktion löst folgenden Fehler aus:
---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt D:\Users\Tobias\Downloads\TXInterface\Test.exe trat ein Problem mit folgender Meldung auf: 'privileged instruction at 0x0018f5a0'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK
---------------------------

"ComPorts" und "EnumComPorts" bauen ja aufeinander auf, das bedeutet, dass der 2. Fehler wohl nur ausgelöst wird, weil bei "ComPorts" keine statische Tabelle mit den einzelnen Ports angelegt wurde. Aber was bedeutet denn "privileged instruction"?

Hoffe ihr könnt mir helfen (:
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 12:23 
Wie sieht denn die Signatur und ggf. die Beschreibung zu dieser Funktion aus?
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 12:38 
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
2.12 GetAvailableComPorts
DWORD GetAvailableComPorts (int selectMode)
Funktion ermittelt auf Basis der Informationen aus der Windows-Registry alle zur Verfügung
stehenden COM-Ports und liefert die Anzahl der Ports zurück. Intern werden diese
Informationen in einer statischen Liste zur weiteren Verwendung verwaltet. Zur Ermittlung
und Anzeige der zur Verfügung stehenden COM-Ports muss diese Funktion zuerst aufgerufen
werden.
Aufruf: int selectMode - Angabe, ob alle COM-Ports gelesen werden oder nur die Ports,
die für eine Verbindung zu einem ROBO-TX Controller
vorgesehen sind (USB oder Bluetooth)
ALL_PORTS 0 alle Ports
USB_ONLY 1 nur USB-Schnittstellen
BT_ONLY 2 nur Bluetooth-Verbindungen
Return: DWORD iComPorts - Anzahl der ermittelten COM-Ports in der internen Liste


Für mich sieht das ja so aus, als ob da iwelche Zugriffsrechte fehlenm aber es ist doch die selbe DLL :/
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 13:37 
Wie ist es denn so?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
const
  ALL_PORTS = 0;
  USB_ONLY  = 1;
  BT_ONLY   = 2;
  
procedure TForm1.Button1Click(Sender: TObject);
const
  MAX_STRLEN = 1024;
var
  test: AnsiString;
  i: DWORD;
begin
  Init();
  for i := 0 to ComPorts(USB_ONLY) - 1 do
    begin
      SetLength(test, MAX_STRLEN);
      ZeroMemory(@test[1], Length(test));
      EnumComPorts(i, PAnsiChar(test), Length(test));
      SetLength(test, StrLen(PAnsiChar(test)));
      ShowMessage(test);
    end;
end;

Für diesen Beitrag haben gedankt: Frolo
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 15:33 
Gleiche Problem sry
---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt D:\Users\Tobias\Downloads\TXInterface\Test.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0x00447da7: read of address 0x01af36f3'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK
---------------------------

Und wie gesagt tritt ja schon ein Fehler auf, alleine beim Aufruf von "ComPorts"...
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 16:02 
Dann weiß ich leider im Moment auch nicht weiter :(

[edit] Nur zur Sicherheit: es sind aber beides 32Bit-Anwendungen? [/edit]
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 16:20 
Jap sind es o:

Soll ich die DLL mal uppen?
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 17:02 
Bist Du sicher, dass Du das darfst? Ich wäre damit vorsichtig.
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 17:22 
Nein bin ich nicht, aber hier:

www.fischertechnik.d...loads/Computing.aspx

einfach bei "ROBO TX Controller" das runterladen: "PC Programming ROBO TX Controller Version 1.5 - 3,2 MB" Da ist sowohl die Dokumentation drinnen als auch die DLL :) Danke schonmal!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 18:32 
So, ich habe das gerade mal unter XE versucht, scheitere aber bereits beim Aufruf von ftxIsLibInit, da kommt FTLIB_ERR_LIB_IS_NOT_INITIALIZED zurück.
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 19:05 
Übernehm doch einfach meinen Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  test: DWord;

implementation

{$R *.dfm}

function GetVer(): DWORD; stdcallexternal 'ftMscLib.dll' name 'ftxGetLibVersion';
function Init(): DWORD; stdcallexternal 'ftMscLib.dll' name 'ftxInitLib';
function ComPorts(mode: Integer): DWORD; stdcallexternal 'ftMscLib.dll' name 'GetAvailableComPorts';
//DWORD GetAvailableComPorts (int selectMode)
function EnumComPorts(idx: DWORD; comstr:PAnsiChar; maxlen: DWORD): DWORD; stdcallexternal 'ftMscLib.dll' name 'EnumComPorts';
//DWORD EnumComPorts (DWORD idx,LPSTR comstr,DWORD maxlen)

procedure TForm1.Button1Click(Sender: TObject);
const
  MAX_STRLEN = 1024;
var
  test: AnsiString;
begin
  Init();
  {ShowMessage(IntToStr(round((GetVer() and 16711680) / 65536)) + '.' +
  IntToStr(round((GetVer() and 65280) / 256)) + '.' + IntToStr(round(GetVer() and 255)));  }

  ShowMessage(IntToStr(ComPorts(1)));
  SetLength(test, MAX_STRLEN);
  EnumComPorts(0, PAnsiChar(test), Length(test));
  SetLength(test, StrLen(PAnsiChar(test)));
  ShowMessage(test);
end;

end.


Der läuft unter Delphi XE3 perfekt (ohne diese Fehlermeldung) bei Delphi 7 auch, nur kommt am ende der procedure diese Meldung..
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 19:36 
Prüf doch mal den Rückgabewert von Init(), das ist ja nicht umsonst eine Funktion. Möglicherweise müsste ich auch erst den ganzen Treiberkrams installieren, aber so weit möchte ich nicht gehen.
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: So 24.02.13 19:46 
Das versteh ich eh nicht so 100%. Wo sind denn die Konstanten definiert? :P Ich hab das nämlich nicht gefunden und die Treiber brauchst du für die Funktionen noch nicht erst später

EDIT:// Leute das Problem hat sich geklärt, aber wie ey oO Ich hab einfach mal zum testen den Rückgabewert von Init() in einer Variable gespeichert und jetzt gehts :) verkehrte Welt o:

Der Fehler taucht bei kleinsten Umstellungen wieder auf, vllt liegt es an dem Typ DWORD?



EDIT2:// Habe die Konstanten gefunden
Blup
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173
Erhaltene Danke: 43



BeitragVerfasst: Mo 25.02.13 11:02 
Eventuell muss "cdecl" statt "stdcall" angegeben werden.

de.wikipedia.org/wiki/Aufrufkonvention