www.mikrocontroller.net

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


Autor: BerndB (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: BerndB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte PC-Programmierung.
DANKE!

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: BerndB (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
private: System::Void send_DMX(int iChannel){
 //FT_HANDLE handle; deklariert in public
 LPVOID *lpBuffer = (char)0; 
 DWORD b = 1;      //Anzahl der Bytes
 LPDWORD lngBytesWritten = 0;
 //break signal
 FT_SetBreakOn(handle);
 FT_SetBreakOff(handle);
//write start code = 0        
if(FT_Write(handle, lpBuffer, b,lngBytesWritten)==FT_OK) //hier Fehlermeldung

lstLoggerList->Items->Add("FT_Write Startcode erfolgreich ausgeführt!");
 else
lstLoggerList->Items->Add("Fehler bei FT_Write Startcode!");
}//end function

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

Autor: BerndB (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
 LPVOID *lpBuffer = (char)0; 
...
if(FT_Write(handle, lpBuffer, b,lngBytesWritten)==FT_OK) //hier Fehlermeldung
...

Was hättest du denn hier erwartet?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  char Buffer[50] = "Hallo World";
  DWORD BytesToWrite = strlen( Buffer );
  DWORD BytesWritten = 0;

  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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
private: System::Void send_DMX(int iChannel)
{
  BYTE bData;

  DWORD dwBytesWritten = 0;

  //write start code = 0        
  bData = 0;

  if (FT_Write(handle, &bData, sizeof (bData), &dwBytesWritten) == FT_OK)
  {
   // etc.pp.
  } 

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

Autor: BerndB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: ich habe fertig (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!!

Autor: BerndB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider meckert der Compiler weil er BYTE nicht kennt!?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

dann nimm unsigned char

Autor: BerndB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super es klappt!!!

Ich danke euch Allen!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.