Forum: PC-Programmierung Probleme mit Variablen bei Ansteuerung eines FTD232


von BerndB (Gast)


Lesenswert?

Hallo,
es geht um die Schreib-Funktion eines FTD232-Bausteins den ich mit einer
in Windows-Form Anwendung ansprechen möchte.

FT_Write(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD
lpBytesWritten)

Mein C++/CLI Compiler meldet keine Fehler, aber bei Ausführung dieser
Funktion kommt eine Fehlermeldung über eine Speicherplatzverletzung
hoch.
Wahrscheinlich habe ich bei der Deklaration zu dieser Variable (LPVOID
lpBuffer) einen Fehler gemacht.
Wenn ich diese Funktion in VisualBasic mit den Typen FT_Write(integer,
string, integer, integer) laufen lasse funktioniert es.
Kann mir jemand mitteilen wie man LPVOID, DWORD und LPDWORD richtig
deklariert?

Vielen Dank!
Bernd

von Klaus W. (mfgkw)


Lesenswert?

Welchen Thread willst du jetzt haben?
Diesen oder http://www.mikrocontroller.net/topic/186322 ?

von BerndB (Gast)


Lesenswert?

Bitte PC-Programmierung.
DANKE!

von Klaus W. (mfgkw)


Lesenswert?

"Speicherplatzverletzung" hört sich nach Hardwareproblem an.
Vielleicht meinst du "Speicherschutzverletzung"?

Deine Angaben sind etwas dürftig, aber mal ins Blaue:
- an der Deklaration wird es kaum liegen, das würde der Compiler 
anmäkeln
- bist du sicher, daß du einen vernünftigen Wert übergibst und nicht 
etwa NULL oder sowas?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

BerndB schrieb:
> FT_Write(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD
> lpBytesWritten)
>
> Mein C++/CLI Compiler meldet keine Fehler, aber bei Ausführung dieser
> Funktion kommt eine Fehlermeldung über eine Speicherplatzverletzung
> hoch.

Dann poste Deinen Code. Wie hast Du die Funktion aufgerufen?

Nicht erklären, Code zeigen.

von Karl H. (kbuchegg)


Lesenswert?

Rufus t. Firefly schrieb:
> BerndB schrieb:
>> FT_Write(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD
>> lpBytesWritten)
>>
>> Mein C++/CLI Compiler meldet keine Fehler, aber bei Ausführung dieser
>> Funktion kommt eine Fehlermeldung über eine Speicherplatzverletzung
>> hoch.
>
> Dann poste Deinen Code. Wie hast Du die Funktion aufgerufen?

Und vor allen Dingen, wie sind die Variablen definiert, die du der 
Funktion übergibst.

Merke: Nicht jeder Pointer in einer Argumentliste bedeutet, dass du eine 
Pointervariable brauchst. In den meisten Fällen ist der Pointer ein 
Indiz dafür, dass du ein Array oder eine Struktur anlegen musst, deren 
Adresse an die Funktion übergeben wird.

Letzteres ist insbesondere praktisch immer der Fall, wenn die Funktion 
ziemlich offensichtlich diese Adresse dazu benutzt um an dieser Stelle 
im Speicher Werte abzulegen oder von dort zu lesen, so wie in deinem 
Fall.

Deine Aussage
> Wahrscheinlich habe ich bei der Deklaration zu dieser
> Variable (LPVOID lpBuffer) einen Fehler gemacht.
lässt mich genau in diese Richtung vermuten: Du hast eine LPVOID 
Variable angelegt. Und das war dann genau das Falsche. Was du tun 
müsstest ist ein Array (von Bytes) anzulegen und dessen Start-Adresse an 
der Stelle lpBuffer durchzuschleusen.

von BerndB (Gast)


Lesenswert?

Also hier die Fehlermeldung nach fehlerfreien Compilieren:

Es wurde versucht im geschützten Speicher zu lesen oder zu schreiben.
Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt 
ist.

Meine Funktion:
1
private: System::Void send_DMX(int iChannel){
2
 //FT_HANDLE handle; deklariert in public
3
 LPVOID *lpBuffer = (char)0; 
4
 DWORD b = 1;      //Anzahl der Bytes
5
 LPDWORD lngBytesWritten = 0;
6
 //break signal
7
 FT_SetBreakOn(handle);
8
 FT_SetBreakOff(handle);
9
//write start code = 0        
10
if(FT_Write(handle, lpBuffer, b,lngBytesWritten)==FT_OK) //hier Fehlermeldung
11
12
lstLoggerList->Items->Add("FT_Write Startcode erfolgreich ausgeführt!");
13
 else
14
lstLoggerList->Items->Add("Fehler bei FT_Write Startcode!");
15
}//end function

[Edit: Durch Einschließen des Codes in [ c ] / [ / c ] wird das ganze 
etwas lesbarer. Rufus]

von BerndB (Gast)


Lesenswert?

Hallo Rufus,
danke für deine Mühe!!!
Kannst du mir ein Beispiel zeigen wie ich dieses Array richtig anlege 
und die Anfangsadresse übergebe?

von g457 (Gast)


Lesenswert?

> LPVOID *lpBuffer = (char)0;
[..]
> LPDWORD lngBytesWritten = 0;
[..]
> FT_Write(handle, lpBuffer, b,lngBytesWritten)

Kokrrektur:
char cBuffer = $blubber;  // was willst du eigentlich übertragen?
[..]
DWORD dBytesWritten = 0;
[..]
FT_Write(handle, &cBuffer, b, &dBytesWritten)

..noch sinnvolle Werte eintragen, dann sollte es klappern.

von Klaus W. (mfgkw)


Lesenswert?

1
 LPVOID *lpBuffer = (char)0; 
2
...
3
if(FT_Write(handle, lpBuffer, b,lngBytesWritten)==FT_OK) //hier Fehlermeldung
4
...

Was hättest du denn hier erwartet?

von Karl H. (kbuchegg)


Lesenswert?

1
  char Buffer[50] = "Hallo World";
2
  DWORD BytesToWrite = strlen( Buffer );
3
  DWORD BytesWritten = 0;
4
5
  FT_Write( handle, Buffer, BytesToWrite, &BytesWritten );

Ist doch einfach:

Im Array Buffer steht das drinnen, was zu senden ist.
Die Funktion will die Startadresse davon haben, also kriegt sie die 
auch.

Nun kann es natürlich sein, dass das Array größer ist, als die die darin 
enthaltenen Daten. Also will die Funktion auch nich wissen, wieviele 
Bytes aus diesem Buffer zu übertragen sind. Auch das geben wir ihr mit, 
im nächsten Argument.

Und zu guter letzt möchte die Funktion auch noch die Adresse einer DWORD 
Variablen haben, in die sie hineinschreibt, wieviele Bytes tatsächlich 
gesendet werden konnten.

Buffer und BytesToWrite gehen in die Funktion hinein. Da es sich bei 
Buffer um ein Array handelt, wird dieses Argument in Form eines Pointers 
übergeben.
BytesWritten hingegen ist anders. Die Funktion möchte darüber dem 
Aufrufer etwas mitteilen. Und daher benötigt sie einen Pointer dafür. So 
quasi: Wo bitte darf ich dir meine Ergüsse hinschreiben? Aha, in deine 
Variable BytesWritten. Gut dass du mir die Adresse davon gegeben hast, 
dann kann ich das dann dort in den Speicher schreiben.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du rufst die Funktion FT_Write auf, sagst ihr aber nicht, was sie 
schreiben soll, aber wieviel.

Und das ist nicht alles.


Also:

  FT_Write(handle, lpBuffer, b,lngBytesWritten)

Hier muss lpBuffer auf die Daten zeigen, die Du schreiben willst.
b enthält die Anzahl der zu schreibenden Bytes, und in
lngBytesWritten steht die Adresse einer Variablen drin, in der die 
Funktion zurückgibt, wieviele Bytes sie tatsächlich geschrieben hat.

Du übergibst aber sowohl für lpBuffer als auch für lngBytesWritten einen 
NULL-Pointer.

Das geht komplett in die Hose.

Vermutlich willst Du als "start code" ein Byte mit dem Wert 0 versenden.


Also sollte das ganze so aussehen:
1
private: System::Void send_DMX(int iChannel)
2
{
3
  BYTE bData;
4
5
  DWORD dwBytesWritten = 0;
6
7
  //write start code = 0        
8
  bData = 0;
9
10
  if (FT_Write(handle, &bData, sizeof (bData), &dwBytesWritten) == FT_OK)
11
  {
12
   // etc.pp.
13
  }

Und wenn Du die Kanalnummer iChannel als 16-Bit-Wert versenden willst, 
sieht der Aufruf so aus:
1
  if (FT_Write(handle, &iChannel, sizeof (iChannel), &dwBytesWritten) == FT_OK)
2
  {
3
   // etc.pp.
4
  }

von BerndB (Gast)


Lesenswert?

Danke!

Ich möchte eine 0 übertragen die als Startbyte des AVR's interprettiert 
wird.

von Karl H. (kbuchegg)


Lesenswert?

Du darfst bei Funktionen nicht einfach nur in die Argumentliste schauen, 
alle Datentypen die du dort findest als Variablen definieren und dann 
die Funktion aufrufen! Du musst schon auch ein wenig nachdenken, was 
denn die Funktion mit dem Argument machen wird, welchen Zweck dieses 
Argument hat und wie es die Funktion verwenden wird. Dann wird nämlich 
in den meisten Fällen sofort klar, was es insbesondere mit einem Pointer 
in der Argumentliste auf sich hat und was man als Aufrufer tun muss um 
dieses Pointerargument korrekt zu bedienen.


Edit:
> Ich möchte eine 0 übertragen die als Startbyte des AVR's
> interprettiert wird.

OK. Das muss daher dann wie aussehen?

von ich habe fertig (Gast)


Lesenswert?

Donald E. Knuth 'The art of computer programming' 1972

"Pointers are a step backwards from witch we will never recover"

Wie recht er hatte!!

von BerndB (Gast)


Lesenswert?

Leider meckert der Compiler weil er BYTE nicht kennt!?

von Karl H. (kbuchegg)


Lesenswert?

BerndB schrieb:
> Leider meckert der Compiler weil er BYTE nicht kennt!?

dann nimm unsigned char

von BerndB (Gast)


Lesenswert?

Super es klappt!!!

Ich danke euch Allen!!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.