Seite 1 von 1

const void* in Objekttyp umwandeln.

Verfasst: Mo Apr 16, 2012 7:05 pm
von Bebu
Hallo zusammen,

ich habe gerade ein kleines Testprogram geschrieben, um die Möglichkeiten von Sqlite mit binären Daten zu testen:

Code: Alles auswählen

#include <iostream>
#include <sqlite3.h>
#include <boost/filesystem.hpp>


int main (void)
{

  sqlite3 *db;
  sqlite3_stmt *stmt=0;

  boost::filesystem::path DbPath( "test.db" );

  sqlite3_open(DbPath.c_str(), &db);

  boost::filesystem::path Pfad( "ööei/ieie'" );

  std::string Sql( "INSERT INTO dbtable VALUES( ? );");

  sqlite3_prepare_v2( db, Sql.c_str(), Sql.size(), &stmt, 0 );

  sqlite3_bind_blob(stmt, 1, reinterpret_cast<const void*>(&Pfad), sizeof( boost::filesystem::path),SQLITE_TRANSIENT);

  sqlite3_step( stmt );

  sqlite3_finalize( stmt );

  Sql = "SELECT * From dbtable WHERE blobfield=(?);";

  sqlite3_prepare_v2( db, Sql.c_str(), Sql.size(), &stmt, 0 );

  sqlite3_bind_blob(stmt, 1, reinterpret_cast<const void*>(&Pfad), sizeof( boost::filesystem::path),SQLITE_TRANSIENT);

  sqlite3_step( stmt );
  //std::cout << sqlite3_column_name( stmt, 0) << std::endl;

  const void * ptr(NULL);
  boost::filesystem::path *pptr(NULL);

  ptr = sqlite3_column_blob( stmt, 0 );

  pptr = reinterpret_cast<boost::filesystem::path*>(&ptr);

  sqlite3_finalize( stmt );

  sqlite3_close( db );

  std::cout << Pfad << std::endl;
  std::cout << *pptr << std::endl;

  return 0;
}
Es sieht furchtbar aus, ich weiß und ich fange nirgends Fehler ab, aber ist ja nur ein Test. Ich weiß, das von Select eine Column zurückgegeben wird, aber die letzte Ausgabe von *pptr ist ein leerer String. Habe ich irgendwo einen Denkfehler? Oder kann ich mir die häßlichen Casts irgendwie sparen?

Re: const void* in Objekttyp umwandeln.

Verfasst: Mo Apr 16, 2012 7:34 pm
von Xin
Funktioniert das mit dem Casting nach void von "Path"?
Ist sizeof( boost::filesystem::path ) nicht kleiner als size()?

Ich glaube nicht, dass das so funktionieren kann. Ich würde mich rein auf den C-String beschränken.

Re: const void* in Objekttyp umwandeln.

Verfasst: Mo Apr 16, 2012 9:57 pm
von fat-lobyte
Nein, das funktioniert ziemlich sicher nicht :-)
Wenn ich das richtig verstanden habe ist boost::filesystem::path nicht einfach ein Array, sondern ein komplexeres Objekt, das auch andere Member haben kann, ähnlich wie std::string.

Zum schreiben von bf::path sollte es eine Art c_str() methode geben, zum Lesen brauchst du zuerst einen char* Zeiger, und musst das irgendwie in den bf::path-Konstruktor reinquetschen.

Übrigens: casts von irgendwas nach void* und vor allem const void* sollten regulär möglich sein, das heißt entweder mit static_cast<>(), oder ganz ohne, wenn du den Zeiger als Funktionsparameter übergibst.
Du brauchst den reinterpret_cast nur, wenn du einen void* nach irgendwas anderes casten willst.

Meine (persönlichen) Regeln für Casts:
const_cast verboten,
dynamic_cast zu vermeiden,
reinterpret_cast zu vermeiden (nur für Bitpfuschereien erlaubt),
static_cast bevorzugen

[edit] Ok, momentchen mal. Das wird doch funktionieren!
Aber nur solange du dich im gleichen Prozessraum befindest, und solange das Ursprüngliche "Path"-Objekt noch am Leben ist! Allerdings hat das mit dauerhafter Speicherung nix mehr zu tun, weil du quasi eine "binäre" Kopie der variablen anlegst, stellt dir das wie ein memcpy() des Objekts vor, nur statt in einen Speicherbereich schreibst du in die Datenbank.

Re: const void* in Objekttyp umwandeln.

Verfasst: Mo Apr 16, 2012 10:35 pm
von Xin
fat-lobyte hat geschrieben:Meine (persönlichen) Regeln für Casts:
const_cast verboten,
dynamic_cast zu vermeiden,
reinterpret_cast zu vermeiden (nur für Bitpfuschereien erlaubt),
static_cast bevorzugen
Yepp, so muss das.
fat-lobyte hat geschrieben:[edit] Ok, momentchen mal. Das wird doch funktionieren!
Aber nur solange du dich im gleichen Prozessraum befindest, und solange das Ursprüngliche "Path"-Objekt noch am Leben ist!
Ich glaube nicht, dass das semantisch mit einer SQL-Datenbank in Einklang zu bringen ist...
fat-lobyte hat geschrieben:Allerdings hat das mit dauerhafter Speicherung nix mehr zu tun, weil du quasi eine "binäre" Kopie der variablen anlegst, stellt dir das wie ein memcpy() des Objekts vor, nur statt in einen Speicherbereich schreibst du in die Datenbank.
Und die Kopie des Zeigers, der beim Speichern auf die CString zeigt wird beim Laden vermutlich nicht mehr viel wert ist.

Re: const void* in Objekttyp umwandeln.

Verfasst: Mo Apr 16, 2012 11:30 pm
von fat-lobyte
Xin hat geschrieben:
fat-lobyte hat geschrieben:Allerdings hat das mit dauerhafter Speicherung nix mehr zu tun, weil du quasi eine "binäre" Kopie der variablen anlegst, stellt dir das wie ein memcpy() des Objekts vor, nur statt in einen Speicherbereich schreibst du in die Datenbank.
Und die Kopie des Zeigers, der beim Speichern auf die CString zeigt wird beim Laden vermutlich nicht mehr viel wert ist.
Wenn das alles im selben Prozess stattfindet, und die Originalkopie sogar noch lebt, sollte das funktionieren. Deswegen sagt meine Kristallkugel, dass es läuft.