
Neben einem Umzug habe ich die letzte Zeit an einer Überraschung für unsere Windowsnutzer gearbeitet, die mir hiermit gründlich misslungen ist

Was ist ein 'normaler' String? std::string? char *?Bebu hat geschrieben:Ich habe bisher mit normalen Strings gearbeitet, was unter Linux kein Problem darstellt, weil hier auch ein normaler String im Path Objekt gekapselt ist.
Meine kann es noch nicht. Aber das könnte man ja mal ändern.Bebu hat geschrieben:Unter Windows steckt aber ein wchar_t drinnen. Hier komme ich sowohl mit den normalen Strings, als auch mit Sqlite in Konflikt. Die aktuelle Öffnungsfunktion von Sqlite erwartet einen UTF-8 codierten normalen String. Ich will keine zwei Codeversionen für char und wchar pflegen müssen, ich will die Windowsversion nicht droppen und habe mir keine elegante Lösung ergooglen können. Habt ihr eine Idee, wie man das Problem lösen kann? Ich dachte schon daran, mir eine eigene Stringklasse zu bauen, die konvertieren kann, aber so was gibt es bestimmt schon.
Ich auch nicht, ich weiß nichtmals, was hast Du letztendlich entdeckt hast?Bebu hat geschrieben:Ich habe auch etwas im neuen Standard entdeckt, aber ich weiß noch nicht, ob mir das weiterhilft.
Code: Alles auswählen
std::string EinString( u8"Ich bin ein UTF8 String";
Crosskompilieren ist zwar Nobel, aber nicht die einfachste aller Hürden. Versuchs mal mit nativ, auch wenn du dabei mit Windows arbeiten musst.Bebu hat geschrieben:Hallo zusammen, neues von der Dedupe-Front![]()
Neben einem Umzug habe ich die letzte Zeit an einer Überraschung für unsere Windowsnutzer gearbeitet, die mir hiermit gründlich misslungen istIch wollte euch gerne eine Windowsversion per Crosscompiler erstellen, leider tun sich unerwartete Probleme auf.
Also wer benötigt jetzt native Strings? SQLite? Oder gibt Boost welche zurück?Um die Sql Befehle zusammenzubauen, die Datenbank zu öffnen usw. ist es nötig, auf den nativen String zurückzugreifen, der unter der Haube eines Boost Path Objekts steckt.
Wenn du auch unter Unix wchar_t verwenden könntest wäre das schon mal eine Lösung (bis auf die Tatsache dass du eine Datenbank nicht zwischen Windows und Linux konvertieren könntest, denn wchar_t->32 bit auf Unix, 16 bit auf Windows).Und jetzt kommt das Problem: Ich habe bisher mit normalen Strings gearbeitet, was unter Linux kein Problem darstellt, weil hier auch ein normaler String im Path Objekt gekapselt ist.
Von einer ganzen Klasse würde ich abraten, aber eine konvertierungsfunktion zwischen UTF32->UTF8 oder UTF16->UTF8 könnte gehen. Dafür gibts auf der Unicode-Webseite auch irgendwo Algorithmen in Pseudo-code.Habt ihr eine Idee, wie man das Problem lösen kann? Ich dachte schon daran, mir eine eigene Stringklasse zu bauen, die konvertieren kann, aber so was gibt es bestimmt schon.
Code: Alles auswählen
int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);
Code: Alles auswählen
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
Code: Alles auswählen
void Dataholding::AddFile( Dedupe::FileInfo const &IncomingFile )
{
std::stringstream translateStream;
std::string ExecString;
translateStream
<< "INSERT INTO StoredFiles ( Path, Size, ChangeDate, Type, Hash) VALUES ('"
<< IncomingFile.GetPath().native() << "','"
<< IncomingFile.GetSize() << "','"
<< IncomingFile.GetDateChanged() << "','"
<< IncomingFile.GetType() << "','"
<< IncomingFile.GetHash() << "');";
std::getline( translateStream, ExecString );
SqlExec( ExecString );
}
Schade. Wirklich perfekt testen kann man nur nativ.Bebu hat geschrieben:Dein Tip zum Crosscompilieren ist nobel, scheitert aber an einer Windowsinstallation und der Zeit/Lust eine aufzusetzen.
Das eine ist ein typedef fürs anderewird ein std::wstring oder halt basic_string<wchar_t>
Das ist ein ziemlicher killer. Das würde ich dann nicht machen.Es gibt alternativ noch diese Funktionen für die Datenbanköffnung:Damit verliere ich aber die Möglichkeit, Sqlite in den Mulithreading-Modus zu schalten.Code: Alles auswählen
...
Das Zauberwort heißt template specialization:Jetzt suche ich ein Möglichkeit das ganze zu lösen, ohne Code zu produzieren, der aufwändig für zwei OS gepflegt werden muss.
Code: Alles auswählen
#include <iostream>
const char* UTF16toUTF8(const wchar_t*);
template <typename CharType>
std::basic_string<char> convert_string(const std::basic_string<CharType>&);
template <>
std::basic_string<char> convert_string(const std::basic_string<char>& in)
{
return in;
}
template <>
std::basic_string<char> convert_string(const std::basic_string<wchar_t>& in)
{
const char* out = UTF16toUTF8(in.c_str());
return std::basic_string<char>(out);
}
int main()
{
std::string cs("Ich bin ein char-string");
std::wstring ws(L"Ich bin ein wchar_t-string");
std::string s1(convert_string(cs));
std::string s2(convert_string(ws));
std::cout<<s1<<'\n';
std::cout<<s2<<'\n';
return 0;
}
const char* UTF16toUTF8(const wchar_t*)
{
// ganz komplizierte konvertierungsfunktion
return "Ich wurde konvertiert.";
}