| Autor |
Beitrag |
behbeh
      
Beiträge: 20
Delphi 7
|
Verfasst: Di 09.06.09 13:42
Hallo
vielleicht kann mir ja einer helfen.
Meine PCI Piokarte hat eine Function zum ausgeben von z.B. 100 * 32Bits. in jedem dieser 100 32Bitwerte kann man was abspeichern, was kann von der Karte ausgegeben wird, mit einem vorher definierten Takt.
Die Function ist in der Unit deklariert.
Delphi-Quelltext 1: 2:
| function DO_ContWritePort (CardNumber:Word; Port:Word; var Buffer:Cardinal; WriteCount:Cardinal; Iterations:Word; SampleRate:Double; SyncMode:Word):Smallint;stdcall; |
Wenn ich jetzt mein Array definiere:
Delphi-Quelltext 1: 2:
| var data:Array[0..511]of cardinal; err:integer; | und rufe die function auf:
Delphi-Quelltext 1:
| err:=DO_ContWritePort(0,0,data,sizeof(data),512,1,160000,SYNCH_OP); |
sagt Delphi mir, das die "formalen und die tätsächliche Parameter nicht übereinstimmen"
Was mache ich das falsch, oder wie bekommt man es hin..
Moderiert von Narses: Delphi-Tags hinzugefügt
Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Di 09.06.2009 um 17:07
|
|
SAiBOT
      
Beiträge: 323
Erhaltene Danke: 6
XP SP2; 7
D7; D2009
|
Verfasst: Di 09.06.09 14:07
Hi, versuch es mal so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| function DO_ContWritePort(var Buffer:Cardinal):Smallint;stdcall; begin end;
var data:Array[0..511]of cardinal; c: Cardinal; begin c := Cardinal(@data[0]); DO_ContWritePort(c); end. |
_________________ Debuggers don't remove bugs, they only show them in slow-motion.
|
|
behbeh 
      
Beiträge: 20
Delphi 7
|
Verfasst: Di 09.06.09 15:34
Hallo
schöner Ansatz,
aber klappt leider nicht. Die Ausgnagsdaten sind nicht die, die ich in mein Array reingeschrieben habe.
Selbst wenn ich die Zuweisung c:=cardinal(@data[0]) auskommentiere, kommt das gleiche raus.
Also sieht es so aus, als wenn die function kein Bezug auf das Array hat, sondern irgendwas aus dem PC-Speicher aus gibt.
Sehr schwer fuer mich das zu verstehen.
Hast Du noch einen andere Idee??
Gruss und Dank
Bernd
P.S.
Array fuellen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| while(i<511) do Begin data[i]:=1; data[i+1]:=0; inc(i,2); end; |
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Di 09.06.09 15:56
In Deiner Deklaration Delphi-Quelltext 1: 2:
| function DO_ContWritePort (CardNumber:Word; Port:Word; var Buffer:Cardinal; WriteCount:Cardinal; Iterations:Word; SampleRate:Double; SyncMode:Word):Smallint;stdcall; | steht ja auch nichts von einem Array. Wenn da wirklich "var Buffer:Cardinal" steht, kannst Du nur ein einzelnes Cardinal rausschreiben und WriteCount sollte wahrscheinlich 4 sein (oder 1 je nachdem ob Bytes oder Cardinals gezählt werden, vgl. Spec).
Oder in der Deklaration steht nur var buffer;, dann sollte der Vorschlag von SAiBOT im Prinzip richtig sein. Allerdings wäre const buffer; bessser, da ja nicht in den Buffer geschrieben wird. Hast Du eine C-Beschreibung? Ich vermute, da steht nur ein Pointer.
|
|
behbeh 
      
Beiträge: 20
Delphi 7
|
Verfasst: Di 09.06.09 16:44
Hallo
habe mal die Beschreibung aus dem PDF File kopiert..
In C wird einfach Buffer deklariert und das an die Stelle geschrieben...
Ich bin nicht so gut vertraut damit..
Vielleicht hilft es euch ja...
Danke Bernd
DO_ContWritePort
Description
Performs continuous digital output on the specified digital output
port at a rate closest to the specified rate.
Supported card(s)
7200, 7300A
Syntax:
Microsoft C/C++, Linux C/C++, and Borland C++
I16 DO_ContWritePort (U16 CardNumber, U16 Port, void *Buffer, U32 WriteCount, U16 Iterations, F32 SampleRate, U16 syncMode)
Visual Basic
DO_ContWritePort (ByVal CardNumber As Integer,ByVal Port As Integer, Buffer As Any, ByVal
WriteCount As Long, ByVal Iterations As Integer, ByVal SampleRate As Single, ByVal SyncMode As Integer) As Integer
Parameter(s)
CardNumber ID of the card performing the operation.
Port Digital output port number. For PCI-7200, cPCI-7200,
PCI-7300A, and cPCI-7300A, this argument must be
set to 0.
hier geht drum:
Buffer Starting address of the memory containing the output data. This memory must have been allocated for
enough space to store output data.
WriteCount Number of output operation to be performed.
Iterations Number of times the data in the Buffer is to be output
to the Port. A value of 0 means that digital output
operation proceeds indefinitely. If the digital output
operation is performed synchronously, this argument
must be set to 1.
SampleRate Sampling rate you want for digital output in hertz
(samples per second). Your maximum rate depends
on the card type and your computer system. This
argument is only useful if the DO trigger mode was
set as internal programmable pacer
(TRIG_INT_PACER and TRIG_DO_CLK_TIMER_ACK) by calling
DO_7200_Config() or DO_7300_Config(). For the
other settings, you have to set this argument as
CLKSRC_EXT_SampRate.
SyncMode Tells whether the operation is performed
synchronously or asynchronously. Valid values:
SYNCH_OP Synchronous digital input, that is, the
function does not return until the digital
input operation is completed.
ASYNCH_OP Asynchronous digital input operations
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 09.06.09 16:57
behbeh hat folgendes geschrieben : | Microsoft C/C++, Linux C/C++, and Borland C++
I16 DO_ContWritePort (U16 CardNumber, U16 Port, void *Buffer, U32 WriteCount, U16 Iterations, F32 SampleRate, U16 syncMode) |
Übersetzen wir das mal eben:
Delphi-Quelltext 1:
| function DO_ContWritePort(CardNumber: Word; Port: Word; var Buffer; DWORD WriteCount; Iterations: Word; SampleRate: Single; SyncMode: Word): WordBool; stdcall; external 'bla.dll' |
Den Puffer übergibst Du dann so hier:
Delphi-Quelltext 1:
| err:=DO_ContWritePort(0,0,@data[0],sizeof(data),512,160000,SYNCH_OP); |
Auch wenn da irgenwie bei Dir noch ein Parameter zu viel ist ... Hab mal 160000 als SampleRate angenommen
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
behbeh 
      
Beiträge: 20
Delphi 7
|
Verfasst: Do 11.06.09 10:18
Hallo alle, BenBe!
vielen Dank fuer deine Umsetzung, von C nach Delphi.
Die ist aber schon in der beiliegenden Unit vorhanden.
Mein Problem ist, da steht "var Buffer:Cardinal". In der Beschreibung steht aber, das es der Anfang des Speichers übergeben wird, (ist ja auch logisch, da sollen doch die Daten drin stehen, die ausgeben werden sollen),
Wie kann ich denn also den Zeiger auf den Anfang meines Arrays in der cardinal deklarieten Variable schreiben.
Wie oben beschrieben (c:=cardinal(@data[0]); )habe ich auch getestet, aber scheinabr kommen nicht die Daten aus diesen Speicherbereich aus der KArte raus.
Ich kann auch mal das PDF File dazu posten, es gibt es auch bei"www.adlicktech.com" hier die PCI7200.
Zuvor habe ich das auch darin enthaltene AkxtivX Modul in Delphi getestet, das klappt prima damit, allerdings gibt es da eine zu grosse Verzögerung bei dem "DO_Commplett-Ereigniss".
Deshalb gab mir der Support den Tip mit der DLL...
Vielleicht hat ja jemand eine Idee. Ich bin mit Deplhi ab 2.0 zwar schon ein paar Jahre damit vertraut, aber wenn es um solche Sachen geht, bin ich zu doof oder zu alt(51)...
Montag bin ich wieder in der Firma, da kann ich weiter testen am Projekt..
Schönes We alle
Bernd
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 11.06.09 12:48
behbeh hat folgendes geschrieben : | Hallo alle, BenBe!
vielen Dank fuer deine Umsetzung, von C nach Delphi.
Die ist aber schon in der beiliegenden Unit vorhanden.
Mein Problem ist, da steht "var Buffer:Cardinal". In der Beschreibung steht aber, das es der Anfang des Speichers übergeben wird, (ist ja auch logisch, da sollen doch die Daten drin stehen, die ausgeben werden sollen),
Wie kann ich denn also den Zeiger auf den Anfang meines Arrays in der cardinal deklarieten Variable schreiben. |
Bitte achte einmal ganz genau, wie ich Puffer deklariert hab: Typenlos. D.h. Wenn Du dort eine beliebige Variable, genauso wie bei Streams in der Write-Methode, übergibst, übergibt er das als Pointer.
behbeh hat folgendes geschrieben : | Wie oben beschrieben (c:=cardinal(@data[0]); )habe ich auch getestet, aber scheinabr kommen nicht die Daten aus diesen Speicherbereich aus der KArte raus.
Ich kann auch mal das PDF File dazu posten, es gibt es auch bei"www.adlicktech.com" hier die PCI7200.
Zuvor habe ich das auch darin enthaltene AkxtivX Modul in Delphi getestet, das klappt prima damit, allerdings gibt es da eine zu grosse Verzögerung bei dem "DO_Commplett-Ereigniss".
Deshalb gab mir der Support den Tip mit der DLL... |
ActiveX in Delphi will ja auch keiner ... Wie gesagt, probier wirklich das mal mit der Übergabe von mir via Stream. Alternativ ersetz mal das var Buffer durch Buffer: PCardinal;. Ist beides (bis auf die Typenprüfung) äquivalent.
behbeh hat folgendes geschrieben : | Vielleicht hat ja jemand eine Idee. Ich bin mit Deplhi ab 2.0 zwar schon ein paar Jahre damit vertraut, aber wenn es um solche Sachen geht, bin ich zu doof oder zu alt(51)...
Montag bin ich wieder in der Firma, da kann ich weiter testen am Projekt..
Schönes We alle
Bernd |
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Do 11.06.09 14:26
Vielleicht noch eine kleine Anmerkung:
Der Parameter Var Buffer:Cardinal ist ja in Wirklichkeit eine Adresse. Nur kann man die hier nicht so übergeben, weil ja ein Cardinal erwartet wird.
Ich kann doch einfach das erste Element des Arrays übergeben (in Wirklichkeit ist das ja die Adresse dieses Elementes, eben wegen dem 'Var').
Delphi-Quelltext 1:
| si := DO_ContWritePort (myCardNumber, myPort, myBuffer[0], ....); |
So blöd ist das gar nicht, denn Du musst ja nicht das erste Element (aka die Adresse des ...) übergeben, sondern kannst z.B. ab der 125. Stelle schreiben:
Delphi-Quelltext 1:
| si := DO_ContWritePort (myCardNumber, myPort, myBuffer[124], ....); |
_________________ Na denn, dann. Bis dann, denn.
|
|
behbeh 
      
Beiträge: 20
Delphi 7
|
Verfasst: Mo 15.06.09 06:12
Hallo und guten Morgen zusammen,
vielen Dank nochmal fuer die Hilfestllung zu meinem Problem. Bin jetzt wieder dran am Programm.
Mal sehen ob Eure Vorschläge funktionieren..
Gruss Bernd
|
|
behbeh 
      
Beiträge: 20
Delphi 7
|
Verfasst: Mo 15.06.09 14:45
Hallo,
Problem scheint gelöst zu sein.
Die Umsetzung von C nach Delphi ist falsch in der beigelegten Unit von der Firma geliefert worden.
Diese Deklaration habe ich geändert.
Delphi-Quelltext 1: 2:
| function DO_ContWritePort (CardNumber:Word; Port:Word; var Buffer:Cardinal; WriteCount:Cardinal; Iterations:Word; SampleRate:Double; SyncMode:Word):Smallint;stdcall; |
Habe mit ein Typ PCardinal = ^Cardinal; gemacht
Diesen eingetragen in den Functionsaufruf und das var gelöscht.
Delphi-Quelltext 1: 2:
| function DO_ContWritePort (CardNumber:Word; Port:Word; --->>Buffer:PCardinal;<------- WriteCount:Cardinal; Iterations:Word; SampleRate:Double; SyncMode:Word):Smallint;stdcall; |
Das ganze aus dem Programm dann so aufgerufen
Delphi-Quelltext 1:
| err:= DO_ContWritePort (Card_id,0,@data,512,1,160000,Synch_op); |
und siehe da, das Ausgabemuster ist so, wie ich es vorher hatte mit dem AKTIVX-Controll...
Vielen Dank nochmal...
Habe da jetzt noch ein kleines Problem, dazu werde ich aber erst einmal suchen und lesen...
Bernd
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mo 15.06.09 15:17
Bernd, es würde auch so wie von mir vorgeschlagen funktionieren.
behbeh hat folgendes geschrieben : | | Die Umsetzung von C nach Delphi ist falsch in der beigelegten Unit von der Firma geliefert worden. |
Dann wärst Du der erste Delphi-Programmierer, der mit dieser Bibliothek arbeitet, oder wieso ist das bisher noch nicht aufgefallen?
_________________ Na denn, dann. Bis dann, denn.
|
|
dummzeuch
      
Beiträge: 593
Erhaltene Danke: 5
Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
|
Verfasst: Mo 15.06.09 20:39
alzaimar hat folgendes geschrieben : | Bernd, es würde auch so wie von mir vorgeschlagen funktionieren.
|
Stimmt, ist aber eher ungewoehnlich.
| Zitat: |
behbeh hat folgendes geschrieben : | | Die Umsetzung von C nach Delphi ist falsch in der beigelegten Unit von der Firma geliefert worden. | Dann wärst Du der erste Delphi-Programmierer, der mit dieser Bibliothek arbeitet, oder wieso ist das bisher noch nicht aufgefallen? |
Vielleicht haben alle anderen sich die Deklaration angeschaut, mit der in C verglichen, ueber die Unfaehigkeit der Ersteller gelacht (oder geflucht) und sie korrigiert? Oder vieleicht haben sie es auch der Firma gemeldet, denen war es aber sch***egal, denn wer benutzt denn heutzutage noch Delphi? Jedenfalls ist das Beschriebene genau die Art von fehlerhafter API-Umsetzung, die mir schon haeufiger untergekommen ist.
Auf der anderen Seite gibt es ziemlich gute APIs, die sogar OOP sind, z.B. von Peak Systemtechnik fuer deren CAN-Bus-Controller, die ich hiermit mal ganz explizit loben will.
twm
|
|
|