SIGSEGV - Segmentation Fault bei dll Funktionsaufruf
SIGSEGV - Segmentation Fault bei dll Funktionsaufruf
Hallo,
ich hatte schon einmal einen Post bezüglich meiner Probleme, Funktionen aus einer dll unter Qt zu verwenden. Beim ersten Thread bin ich davon ausgegangen, dass es sich um ein Timingproblem handelt und ich meine dll-Lesezugriffe irgendwie entkoppeln muss.
Ob es sich um ein Qt-spezifisches Problem handelt, bin ich mir nicht sicher. Meine weiteren Testapplikationen laufen jedenfalls allesamt auf der Kommandozeile und mit dem Microsoft Express C++ 2008 übersetzt.
Mein Problem: Ich bekomme einen "SIGSEGV - Segmentation Fault", wenn ich in meiner Methode eine Schleife verwende, die mehrmals durchlaufen wird und dabei eine Lesefunktion der dll verwendet.
Ich habe drei verschiedene Interfaces, ein Peak CAN Dongle (USB), eine Meilhaus ME4660 und ein PicoScope PS4224. Alle binde ich mit der mitgelieferten dll ein.
1.) Meilhaus funktioniert fehlerfrei - ich kann lesend/schreibend auf IO zugreifen und auch die ADC kanäle lesen
2.) Peak CAN wird mit SIGSEGV Fehler beendet, wenn ich in meiner Lese-Methode mehrfach die dll-Lesefunktion aufrufe (while buffer_read_completely)
3.) PicoScope crasht mit SIGSEGV wenn ich zum DRITTEN mal in meiner Lese-Methode die dll Funktion zum auslesen der Versionsdaten aufrufe.
Interessant ist, dass bei 2.) die App stabil(er) läuft, wenn ich in der Methode nur einmal lese und dafür dann den QTimer zum Aufruf auf eine kürzere Zeit setze (hier 2ms).
Auch kann ich bei 3.) meine Methode beliebig oft nacheinander aufrufen, wenn ich in dieser nicht mehr als zweimal auf die dll Lesefunktion zugreife.
Ich kapier's nicht ! Wenn es mit der Übergabe der Daten (call-by-value und -reference) zusammenhängt, müsste doch schon der erste Zugriff in die Hose gehen ? Wie oben schon erwähnt, funktionieren auch meine Testapplikationen für die Kommandozeile allesamt, die vom Konzept ähnlich aufgebaut sind.
Hoffe, Ihr könnt mir helfen - oder bin ich echt der Einzige, der sich damit schon mal rumgeärgert hat ?
Viele Grüße,
Marcus
ich hatte schon einmal einen Post bezüglich meiner Probleme, Funktionen aus einer dll unter Qt zu verwenden. Beim ersten Thread bin ich davon ausgegangen, dass es sich um ein Timingproblem handelt und ich meine dll-Lesezugriffe irgendwie entkoppeln muss.
Ob es sich um ein Qt-spezifisches Problem handelt, bin ich mir nicht sicher. Meine weiteren Testapplikationen laufen jedenfalls allesamt auf der Kommandozeile und mit dem Microsoft Express C++ 2008 übersetzt.
Mein Problem: Ich bekomme einen "SIGSEGV - Segmentation Fault", wenn ich in meiner Methode eine Schleife verwende, die mehrmals durchlaufen wird und dabei eine Lesefunktion der dll verwendet.
Ich habe drei verschiedene Interfaces, ein Peak CAN Dongle (USB), eine Meilhaus ME4660 und ein PicoScope PS4224. Alle binde ich mit der mitgelieferten dll ein.
1.) Meilhaus funktioniert fehlerfrei - ich kann lesend/schreibend auf IO zugreifen und auch die ADC kanäle lesen
2.) Peak CAN wird mit SIGSEGV Fehler beendet, wenn ich in meiner Lese-Methode mehrfach die dll-Lesefunktion aufrufe (while buffer_read_completely)
3.) PicoScope crasht mit SIGSEGV wenn ich zum DRITTEN mal in meiner Lese-Methode die dll Funktion zum auslesen der Versionsdaten aufrufe.
Interessant ist, dass bei 2.) die App stabil(er) läuft, wenn ich in der Methode nur einmal lese und dafür dann den QTimer zum Aufruf auf eine kürzere Zeit setze (hier 2ms).
Auch kann ich bei 3.) meine Methode beliebig oft nacheinander aufrufen, wenn ich in dieser nicht mehr als zweimal auf die dll Lesefunktion zugreife.
Ich kapier's nicht ! Wenn es mit der Übergabe der Daten (call-by-value und -reference) zusammenhängt, müsste doch schon der erste Zugriff in die Hose gehen ? Wie oben schon erwähnt, funktionieren auch meine Testapplikationen für die Kommandozeile allesamt, die vom Konzept ähnlich aufgebaut sind.
Hoffe, Ihr könnt mir helfen - oder bin ich echt der Einzige, der sich damit schon mal rumgeärgert hat ?
Viele Grüße,
Marcus
Hallo,
ich werde mal den code zusammenstellen. Vom Konzept her ist es immer das selbe gewesen. Das MainWindow habe ich mit dem QDesigner erstellt, dann gibt es die main.c und die MainWindow Klasse und meine PicoScope Klasse. Zuerst habe ich beide Objekte in der main() deklariert und den Pointer von dem PicoScope Objekt an mainWindow übergeben. Das hab' ich geändert, da ich im Destruktor das Interface schliessen und die dll mit unload sauber "abwerfen" wollte...
1. main.cpp
2. MainWindow.cpp - Hauptfenster
4. qtps.h Header mit Klassendefinition
5. qtps.cpp für die Kommunikation
Beim debuggen kann man zwar gut verfolgen, wie die Daten per call-by-reference in dem char Array landen. Beim dritten Zugriff auf die dll Funktion ploppt dann die Fehlermeldung auf und die Überwachung der lokalen Variablen ist gelöscht... und mit den Addressen in der Dateiliste kann ich ehrlich gesagt nicht so richtig was anfangen. Bin halt dann doch eher auf den Microcontrollern zu Hause.
ich werde mal den code zusammenstellen. Vom Konzept her ist es immer das selbe gewesen. Das MainWindow habe ich mit dem QDesigner erstellt, dann gibt es die main.c und die MainWindow Klasse und meine PicoScope Klasse. Zuerst habe ich beide Objekte in der main() deklariert und den Pointer von dem PicoScope Objekt an mainWindow übergeben. Das hab' ich geändert, da ich im Destruktor das Interface schliessen und die dll mit unload sauber "abwerfen" wollte...
1. main.cpp
Code: Alles auswählen
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
int retval;
MainWindow *win = new MainWindow();
win->show();
retval = app.exec();
delete win; // wird sonst scheinbar nicht zerstört, zumindest nicht das ps Objekt
return retval;
}Code: Alles auswählen
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
setupUi(this);
ps = new qtps(); // anlegen des ps Objects - wird im Destruktor gelöscht
if(ps->psDllLoaded)
this->statusBar()->showMessage("PicoScope DLL loaded");
else
this->statusBar()->showMessage("PicoScope DLL failed");
// signal slot associations
QObject::connect(ps, SIGNAL(isOpened()), this, SLOT(portOn()));
connect(ps, SIGNAL(isClosed()), this, SLOT(portOff()));
// ...
}
MainWindow::~MainWindow()
{
delete ps; // löschen, damit das PicoScope wieder freigegeben wird !
}
void MainWindow::on_pushButton_getInfo_clicked(void)
{
textEdit_Debug->append("check PicoScope Unit");
ps->getUnitInfo();
textEdit_Debug->append("ok");
}
Code: Alles auswählen
#ifndef QTPS_H
#define QTPS_H
#include <QObject>
#include <QLibrary> // dll loading support
extern "C"
{
#include "picoscope/ps4000Api.h"
}
/** typedefs for dll import */
typedef PICO_STATUS (*prot_psPspShort) (short* handle);
typedef PICO_STATUS (*prot_psPsShort) (short handle);
typedef PICO_STATUS (*prot_psPsShortShort) (short handle, short start);
typedef PICO_STATUS (*prot_psGetUnitInfo) (short handle, char * string, short stringLength, short * requiredSize, PICO_INFO info);
// ...
class qtps : public QObject
{
Q_OBJECT
public:
qtps();
~qtps();
bool psDllLoaded;
bool psIsOpen;
public slots:
void openUnit(void);
void closeUnit(void);
void getUnitInfo(void);
void debug(void);
signals:
void isOpened(void);
void isClosed(void);
void isDataReady(void);
private:
QLibrary psLib; // use PicoScope DLL
prot_psPspShort ps4000OpenUnit;
prot_psPsShort ps4000CloseUnit; // Function from DLL
prot_psGetUnitInfo ps4000GetUnitInfo;
prot_psPsShortShort ps4000FlashLed;
PICO_STATUS psStatus;
UNIT_MODEL psUnit;
tTriggerDirections directions;
};
5. qtps.cpp für die Kommunikation
Code: Alles auswählen
qtps::qtps()
{
// PicoScope Dll laden
QLibrary psLib("ps4000.dll");
// Funktionen aufloesen
ps4000OpenUnit = (prot_psPspShort) psLib.resolve("ps4000OpenUnit");
ps4000CloseUnit = (prot_psPsShort) psLib.resolve("ps4000CloseUnit");
ps4000FlashLed = (prot_psPsShortShort) psLib.resolve("ps4000FlashLed");
ps4000GetUnitInfo = (prot_psGetUnitInfo) psLib.resolve("ps4000GetUnitInfo");
// initialize public and private variables
psDllLoaded = (ps4000OpenUnit && ps4000CloseUnit &&
ps4000FlashLed && ps4000GetUnitInfo)? true:false;
// set default
closeUnit();
}
qtps::~qtps()
{
if(psIsOpen)
closeUnit();
if(psDllLoaded)
psLib.unload();
}
void qtps::getUnitInfo(void)
{
char line[80]; // besser QByteArray verwenden
int variant;
short i, r;
PICO_STATUS status = PICO_OK;
r=0;
if(psUnit.handle)
{
// for(i=0; i<5; i++)
for(i=0; i<2; i++) // SIGSEGV - Segmentation Fault beim dritten Zugriff auf dll Funktion !?
{
status = ps4000GetUnitInfo(psUnit.handle, line, sizeof(line), &r, i);
}
}
}
- Dateianhänge
-
- Debugger bei/nach SIGSEGV Fehlermeldung
- debug.jpg (99.24 KiB) 6474 mal betrachtet
Das ist unnoetig.. Siehe:und die dll mit unload sauber "abwerfen" wollte...
Wenn es also nur darum geht, kannst du auf die Pointer verzichten.. Beim Ende des Scopes werden Objekte übrigens sowieso zerstört.. also:http://doc.qt.nokia.com/4.0/qlibrary.html#unload hat geschrieben: This happens automatically on application termination, so you shouldn't normally need to call this function.
Code: Alles auswählen
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
MainWindow win;
win.show();
return app.exec();
}
Auf den ersten Blick sehen ich lediglich, dass die Variabel "psLib" einmal lokal
Zweitens sind die Funktionspointer solange gültig, wie die DLL im Speicher besteht. Wehe du entlädst die DLL und rufst danach "qtps::getUnitInfo()"auf!!
Zum Vorgehen: Ich würde sowas unbedingt vorher in einer Testumgebung untersuchen (um andere Fehler auszuschliessen). In einer einzelnen main.cc kannst du problemlos die Library laden und einfach mal alle 7 Infos durch ps4000GetUnitInfo(..) abrufen. Klappt dies, kannst du dich an das grössere Projekt machen und eine saubere Struktur reinbringen.
hth..
Zerstörung ja, aber keine Ausführung des Destruktors
Hallo,
danke für Deine Antwort.
Ich bin auch davon ausgegangen, dass Objekte automatisch zerstört werden. Jedoch ist "Zerstört werden" und "Destruktor ausführen" wohl zweierlei.
Bei der automatischen Zerstörung wird der Code, den ich explizt im Destruktor angegeben habe, nicht ausgeführt, somit bleibt das Interface (PicoScope) geöffnet, da CloseUnit nicht ausgeführt wird und beim Neustart des Programms ist dann kein Zugriff möglich, da das PicoScope immer noch geöffnet ist.
Daher mein Ansatz mit delete, der auch funktioniert.
Ich werde mal alles in die main() verfrachten und schauen, ob die App dann auch crasht.
danke für Deine Antwort.
Ich bin auch davon ausgegangen, dass Objekte automatisch zerstört werden. Jedoch ist "Zerstört werden" und "Destruktor ausführen" wohl zweierlei.
Bei der automatischen Zerstörung wird der Code, den ich explizt im Destruktor angegeben habe, nicht ausgeführt, somit bleibt das Interface (PicoScope) geöffnet, da CloseUnit nicht ausgeführt wird und beim Neustart des Programms ist dann kein Zugriff möglich, da das PicoScope immer noch geöffnet ist.
Daher mein Ansatz mit delete, der auch funktioniert.
Ich werde mal alles in die main() verfrachten und schauen, ob die App dann auch crasht.
Re: Zerstörung ja, aber keine Ausführung des Destruktors
Eigentlich eher nein... Wenn du ein Objekt selber zerstörst dann (hoffentlich) nur wenn das ein Pointer ist, und das machst du mit delete. Das delete ruft aber den Destruktor auf! Danach wird Speicher freigegeben.embweb hat geschrieben:Ich bin auch davon ausgegangen, dass Objekte automatisch zerstört werden. Jedoch ist "Zerstört werden" und "Destruktor ausführen" wohl zweierlei.
Bei automatischer Zerstörung besteht der einzige Unterschied darin, dass du nicht selber delete aufrufst.
Das ist aber ein IrrglaubeBei der automatischen Zerstörung wird der Code, den ich explizt im Destruktor angegeben habe, nicht ausgeführt
Wie gesagt wird der Destruktor aufgerufen.
Versuch es doch einfach mit einer kleinen Testklasse, die im Konstruktor und Destruktor eine kleine Meldung auf die Konsole zaubert, und teste die ganzen Möglichkeiten zur Erstellung/Zerstörung durch.
Test Destruktor
Wie schon gesagt, bin ich ja auch zuerst davon ausgegangen, dass es "automatisch" abläuft.
Wenn ich delete jedoch nicht explizit aufrufe, bleibt die LED am Interface an und wird nicht beendet mit closeUnit. Die main() hatte ich ja zuerst auch so, wie Du oben nochmal gezeigt - ganz klassisch nach Qt-Lehrbuch.
Ich habe den Ansatz mit "alles in die main() und debuggen" noch mal weiter verfolgt...
Irgendwas haut's da kaputt im Speicher. Die for() sollte von 0..4 Zählen. Im Fehlerfall zählt sie bis 3, dann gibt es einen Sprung zurück auf 0 und sie zählt weiter bis 4. Manchmal läuft die for() zu Ende, manchmal gibt es auch wieder nach dem 3. oder 4. Zugriff eine SIGSEGV.
Wenn ich delete jedoch nicht explizit aufrufe, bleibt die LED am Interface an und wird nicht beendet mit closeUnit. Die main() hatte ich ja zuerst auch so, wie Du oben nochmal gezeigt - ganz klassisch nach Qt-Lehrbuch.
Ich habe den Ansatz mit "alles in die main() und debuggen" noch mal weiter verfolgt...
Irgendwas haut's da kaputt im Speicher. Die for() sollte von 0..4 Zählen. Im Fehlerfall zählt sie bis 3, dann gibt es einen Sprung zurück auf 0 und sie zählt weiter bis 4. Manchmal läuft die for() zu Ende, manchmal gibt es auch wieder nach dem 3. oder 4. Zugriff eine SIGSEGV.
Re: Test Destruktor
Verwechlse "Destruktor" nicht mit "Deinitialisierer"!embweb hat geschrieben:Wie schon gesagt, bin ich ja auch zuerst davon ausgegangen, dass es "automatisch" abläuft.
Wenn ich delete jedoch nicht explizit aufrufe, bleibt die LED am Interface an und wird nicht beendet mit closeUnit. Die main() hatte ich ja zuerst auch so, wie Du oben nochmal gezeigt - ganz klassisch nach Qt-Lehrbuch.
Deine Zugriffe auf das Handle sind C. C kennt keine Destruktoren.
Dein "UNIT_MODEL psUnit;" wird auch zerstört. Aber eben die Verbindung nicht geschlossen. Deshalb ist das close auch notwendig.
Re: Test Destruktor
Da wird der Stack zersäbelt. Kannst du mal die komplette main.cc posten?embweb hat geschrieben:[...]Im Fehlerfall zählt sie bis 3, dann gibt es einen Sprung zurück auf 0 und sie zählt weiter bis 4. Manchmal läuft die for() zu Ende, manchmal gibt es auch wieder nach dem 3. oder 4. Zugriff eine SIGSEGV.
[Edit]
Und du verwendest nicht die 32Bit dll unter Windows 7/Vista 64Bit.. oder?
meine Test-main()
Hallo,
nein - kein Visto oder Windows 7. Das System besteht aus einem Intel D945GCLF2 Mainboard mit Atom 330 und 1GB RAM, es ist ein WIndows XP Prof. 32Bit drauf. Parallel wollte ich das ganze später noch auf Ubuntu portieren, jedoch fehlt mir zu einem Interface ein Linux-Treiber.
Anbei mein letzter Stand der Test-main:
Wenn der SIGSEGV Fehler kommt, bleibt er im Debugger in qobject.cpp stehen, und zwar bei:
nein - kein Visto oder Windows 7. Das System besteht aus einem Intel D945GCLF2 Mainboard mit Atom 330 und 1GB RAM, es ist ein WIndows XP Prof. 32Bit drauf. Parallel wollte ich das ganze später noch auf Ubuntu portieren, jedoch fehlt mir zu einem Interface ein Linux-Treiber.
Anbei mein letzter Stand der Test-main:
Code: Alles auswählen
#include <QApplication>
#include <QLibrary>
#define PICO_OK 0x00000000UL
#define PICO_EEPROM_CORRUPT 0x0000000AUL
#define PICO_INFO_UNAVAILABLE 0x0000002AUL
#define PICO_NOT_ENOUGH_SEGMENTS 0x00000042UL
// typedefs
typedef unsigned long PICO_STATUS;
typedef unsigned long PICO_INFO;
typedef PICO_STATUS (*prot_psPspShort) (short* handle);
typedef PICO_STATUS (*prot_psPsShort) (short handle);
typedef PICO_STATUS (*prot_psGetUnitInfo) (short handle, char * string, short stringLength, short * requiredSize, PICO_INFO info);
// prototypes
prot_psPspShort ps4000OpenUnit;
prot_psPsShort ps4000CloseUnit;
prot_psGetUnitInfo ps4000GetUnitInfo;
/** main Process entry...
*/
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QLibrary psLib("ps4000.dll");
static bool DllLoaded;
static bool IsOpen;
static bool failure = false;
static char line[256]; // besser QByteArray etc verwenden
static short i, r=0;
static short handle=0;
static PICO_STATUS retval;
// Funktionen aufloesen
ps4000OpenUnit = (prot_psPspShort) psLib.resolve("ps4000OpenUnit");
ps4000CloseUnit = (prot_psPsShort) psLib.resolve("ps4000CloseUnit");
ps4000GetUnitInfo = (prot_psGetUnitInfo) psLib.resolve("ps4000GetUnitInfo");
// check if assigned
DllLoaded = (ps4000OpenUnit && ps4000CloseUnit && ps4000GetUnitInfo)? true:false;
// test it now
if(DllLoaded)
{
retval = ps4000OpenUnit(&handle);
if((retval != PICO_OK) && (retval != PICO_EEPROM_CORRUPT) )
IsOpen = false;
else
IsOpen = true;
}
// test read access and close unit afterwards
if( (IsOpen== true) && (handle!=0) )
{
for(i=0; i<5; i++) // SIGSEGV - Segmentation Fault beim dritten Zugriff auf dll Funktion !?
{
retval = ps4000GetUnitInfo(handle, line, sizeof(line), &r, i);
switch(retval)
{
case PICO_OK:
failure = false;
break;
case PICO_INFO_UNAVAILABLE:
failure = true;
break;
case PICO_NOT_ENOUGH_SEGMENTS:
failure = true;
break;
default:
failure = true;
break;
}
}
// close Interface
retval = ps4000CloseUnit(handle);
IsOpen = false;
}
return 0;
}
Code: Alles auswählen
/*! \internal
*/
void QObjectPrivate::clearGuards(QObject *object)
{
QObjectPrivate *priv = QObjectPrivate::get(object);
QGuard<QObject> *guard = priv->extraData ? priv->extraData->objectGuards : 0;
...
Zuletzt geändert von embweb am 23. April 2010 10:19, insgesamt 1-mal geändert.
... ach ja, das hatte ich noch vergessen hinzuzufügen:
Die Variablen waren bei meinen ersten Tests zuvor nicht alle static. War nur so eine Vermutung...
Bei beiden Versionen kommt ein SIGSEGV Fehler, einziger Unterschied:
- bei der Version ohne static bleibt er beim Aufruf der
retval = ps4000GetUnitInfo(handle, line, sizeof(line), &r, i); Zeile hängen,
- bei der mit static wie beschrieben in der qobject.cpp
Ich "blick" das nicht... Vielleicht regnet es ja am Wochenende, dann arbeite ich das Qt Handbuch noch mal 'gscheit durch um die Abläufe im Hintergrund mal besser zu verstehen... wobei das Problem wohl, bis auf die Verwendung von QLibrary, wenig mit Qt zu tun hat.
Die Variablen waren bei meinen ersten Tests zuvor nicht alle static. War nur so eine Vermutung...
Bei beiden Versionen kommt ein SIGSEGV Fehler, einziger Unterschied:
- bei der Version ohne static bleibt er beim Aufruf der
retval = ps4000GetUnitInfo(handle, line, sizeof(line), &r, i); Zeile hängen,
- bei der mit static wie beschrieben in der qobject.cpp
Ich "blick" das nicht... Vielleicht regnet es ja am Wochenende, dann arbeite ich das Qt Handbuch noch mal 'gscheit durch um die Abläufe im Hintergrund mal besser zu verstehen... wobei das Problem wohl, bis auf die Verwendung von QLibrary, wenig mit Qt zu tun hat.
Das Problem hängt nicht mit Qt zusammen. Wenn der Stack zerschossen wird, crashed halt irgendwas...
Hast du ein Code-Beispiel vom Hersteller?
[EDIT] geloescht. was überlesen [EDIT]
Hast du ein Code-Beispiel vom Hersteller?
[EDIT] geloescht. was überlesen [EDIT]
Zuletzt geändert von solarix am 23. April 2010 10:23, insgesamt 1-mal geändert.
Hast du schonmal versucht zu checken ob es evtl. an der Abfragefrequenz liegt?
In der Schleife ein
Dann die "0" schrittweise erhöhen.
Desweiteren könntest du den "handle != 0"-Check in der Schleife direkt vor den Aufruf der Funktion setzen.
Desweiteren wäre eine genauere Spezifikation der ps4000*-Funktionen nicht schlecht
*) Parameter
*) erwartete Werte der Parameter
usw
In der Schleife ein
Code: Alles auswählen
retval = ps4000GetUnitInfo(handle, line, sizeof(line), &r, 0);Desweiteren könntest du den "handle != 0"-Check in der Schleife direkt vor den Aufruf der Funktion setzen.
Desweiteren wäre eine genauere Spezifikation der ps4000*-Funktionen nicht schlecht
*) Parameter
*) erwartete Werte der Parameter
usw
@franzf: vermutlich http://www.imex.ie/files/u3/ps4000pg_en_pdf_31123.pdf
@embweb: zeig uns mal das in der Doku erwähnte "ps4000.c".. wenigstens die Funktionspointer-Deklaration daraus..
@embweb: zeig uns mal das in der Doku erwähnte "ps4000.c".. wenigstens die Funktionspointer-Deklaration daraus..
... kann man im Forum Dateien anhängen/hochladen, so dass diese als Link auftauchen? Sonst wird's unübersichtlich.
Die angegebene Doku (Link) ist korrekt. Es ist ein PicoScope 4224.
Allerdings gibt es im SDK keine ps4000.c ... nur die Header und ein Beispiel für MS Express / Kommandozeile.
In der ps4000Api.h ist die Funktion wie folgt definiert :
wobei die ganzen PREFx zuvor per #define in Abhängigkeit vom System gesetzt werden. Also :
PICO_INFO ist als unsigned long in der picoStatus.h definiert, so wie in meiner Test-main auch. Es gibt 5 Einträge, die damit selektiert werden können (index 0..4), z.B. die Serien-Nr, Typ, USB Support, Firmware etc.
Die angegebene Doku (Link) ist korrekt. Es ist ein PicoScope 4224.
Allerdings gibt es im SDK keine ps4000.c ... nur die Header und ein Beispiel für MS Express / Kommandozeile.
In der ps4000Api.h ist die Funktion wie folgt definiert :
Code: Alles auswählen
PREF0 PREF1 PICO_STATUS PREF2 PREF3 (ps4000GetUnitInfo)
(
short handle,
char * string,
short stringLength,
short * requiredSize,
PICO_INFO info
);Code: Alles auswählen
#ifdef __cplusplus
#define PREF0 extern "C"
#define TYPE_ENUM
#else
#define PREF0
#define TYPE_ENUM enum
#endif
#ifdef WIN32
typedef unsigned __int64 u_int64_t;
#ifdef PREF1
#undef PREF1
#endif
#ifdef PREF2
#undef PREF2
#endif
#ifdef PREF3
#undef PREF3
#endif
/* If you are dynamically linking PS4000.DLL into your project #define DYNLINK here
*/
#ifdef DYNLINK
#define PREF1 typedef
#define PREF2
#define PREF3(x) (__stdcall *x)
#else
#define PREF1
#ifdef _USRDLL
#define PREF2 __declspec(dllexport) __stdcall
#else
#define PREF2 __declspec(dllimport) __stdcall
#endif
#define PREF3(x) x
#endif
#else
...