2016-04-13 9 views
1

Bitte korrigieren Sie mich, wo ich falsch verstanden habe.Warum ist das für sqlite3_open verwenden wir Doppelzeiger ** und für sqlite3_prepare verwenden wir Zeiger *

Ich lese diese Antwort https://stackoverflow.com/a/833124/5175709 und was ich verstand war, dass, da das Objekt erweitern konnte und nicht genügend Platz, dann die Speicherstelle meine auch ändern.Aber hier verweisen zwei SQLite3-Syntaxen auf das Objekt anders. WARUM?

sqlite3_open haben wir: sqlite3 **ppDb

SQLITE_API int SQLITE_STDCALL sqlite3_open(
    const char *filename, /* Database filename (UTF-8) */ 
    sqlite3 **ppDb   /* OUT: SQLite db handle */ 

Und für sqlite3_prepare haben wir: sqlite3 *db

SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
    sqlite3 *db,   /* Database handle */ 
    const char *zSql,  /* SQL statement, UTF-8 encoded */ 
    int nByte,    /* Maximum length of zSql in bytes. */ 
    sqlite3_stmt **ppStmt, /* OUT: Statement handle */ 
    const char **pzTail  /* OUT: Pointer to unused portion of zSql */ 

Antwort

2

sqlite3_open Bedürfnisse Sie irgendwie geben Sie eine Datenbank-Verbindungsobjekt; ein sqlite3 Objekt.

Um zu verhindern, dass Personen auf die Interna zugreifen, deklariert sqlite3.hsqlite3 als undurchsichtige Struktur. Dies bedeutet, dass Sie keinen Platz für eine sqlite3 reservieren können, da Sie nicht wissen, was es enthält; Die SQLite-Bibliothek muss sie für Sie reservieren und Ihnen einen Zeiger darauf geben (sqlite3*).

Nun haben wir eine hypothetische Funktion sqlite3* sqlite3_open(...);, die einen DB öffnet und einen Zeiger auf das Verbindungsobjekt zurückgibt. Aber halt dich fest; Was passiert, wenn ein Fehler auftritt? Wir könnten NULL zurückgeben, aber wie soll der Entwickler einen "Datenbank existiert nicht" -Fehler von einer "Datenbank ist nur lesbar", "Datenbank ist beschädigt" oder anderen Fehlern unterscheiden?

Stattdessen gibt sqlite3_open einen Ganzzahl-Rückgabecode zurück und schreibt den Verbindungszeiger auf den Speicher, auf den der ppDB-Parameter zeigt, wenn das Öffnen erfolgreich war.

sqlite3_open ist in der Regel wie folgt verwendet:

sqlite3* myDB; 
int status = sqlite3_open("/path/to/db", &myDB); 
if(status != SQLITE_OK) { 
    // error occured 
    return; 
} 
// sqlite3_open wrote a database pointer to myDB, use it here 
status = sqlite3_prepare_v2(myDB, "SELECT * FROM whatever", -1, NULL, NULL); 
// ... 
+0

Ausgezeichnete Antwort C32, danke. Sie sagen also, der einzige Grund, warum wir das tun, ist Schutz? Wenn also ein Fehler auftritt, würde sqlite3 * auf "nil" zeigen. Was ist mit der Speichererweiterung? Ich bin immer noch verwirrt. Können Sie das bitte näher ausführen? – Honey

+0

@ asma22 Der einzige Weg, um festzustellen, ob ein Fehler auftritt, ist der Blick auf den Rückgabewert. [SQLite wird weiterhin einen Datenbankzeiger schreiben, selbst wenn er nicht geöffnet werden konnte] (http://sqlite.org/c3ref/open.html) (wahrscheinlich, damit Sie eine Fehlermeldung erhalten). Da die genaue Struktur der 'sqlite3'-Struktur mit SQLite vor dem Programm verborgen ist, kann SQLite Felder daraus hinzufügen oder entfernen (was die Menge des verwendeten Speichers ändern kann), ohne die API oder ABI zu zerstören. –

Verwandte Themen