C/C++で多言語対応でクロスプラットフォーム!
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2009/09/21(月) 12:26:51やっぱり基本はC/C++!
C/C++で多言語を使えて
しかもクロスプラットフォームな
アプリを作るノウハウを集めましょう。
0002デフォルトの名無しさん
2009/09/21(月) 12:32:070003デフォルトの名無しさん
2009/09/21(月) 12:33:07BoostでMTなんかも片付くし、あと何か困ることある? GUIとか?
GUIはクロスプラットフォームにしてもしょぼくなりがちだしなぁ…
0004デフォルトの名無しさん
2009/09/21(月) 12:34:22間違っていたら訂正よろ
多言語対応にするには、内部をUNICODEで扱うのが一番。
一つの方法として、多言語対応の文字列クラスを提供している
クロスプラットフォームライブラリを使う方法がある。
(たとえば内部がUnicode化されているQtのQString)
が、既存の英語版アプリを日本語(多言語)対応にする場合、
そこにライブラリを導入して、文字列を全て変更するのは大変。
0005デフォルトの名無しさん
2009/09/21(月) 12:40:39wchar_tっていうだけじゃエンコード(UTF-8なのかUTF-16なのか)がわからない。
それから、たとえばフォルダの中のファイルを全部テキストファイルに出力するとして、
ファイル名にUNICODE文字列(日本語以外)が含まれている場合、
どういう方法をとれば、クロスプラットフォームにできるか。という話。
0006デフォルトの名無しさん
2009/09/21(月) 12:40:420007デフォルトの名無しさん
2009/09/21(月) 12:41:100008デフォルトの名無しさん
2009/09/21(月) 12:44:39UNICODEが定義してあるかどうかで、
_tcs〜関数が、str〜とwcs〜に置き換わる。
0009デフォルトの名無しさん
2009/09/21(月) 12:48:09ICUでも使えば
0010デフォルトの名無しさん
2009/09/21(月) 12:55:31その文字列はUTF-8?
UTF-8であれば、文字列型はcharのままで良いし、
printfで出力できる。なぜならUTF-8はANSIの
ように見えるように作られているから。
しかし、これがUTF-16であれば話が違ってくる。
UTF-16ならcharではなくwchar_tを使う必要がある。
wchar_tを使うと、printfではなくwprintfを使わないといけなくなる。
既存のアプリを修正する場合、変更の労力と影響範囲が違ってくる。
Windows API・・・たとえばMessageBoxは
ANSI版のMessageBoxAとUNICODE版のMessageBoxWがある。
WindowsにおけるUNICODEとはUTF-16LE。
文字列をUTF-8にすると、UTF-16LEに変換してからAPIに渡す必要がある。
クロスプラットフォームまで考えるといろいろと大変。
クロスプラットフォームライブラリを使いたいところだが、
既存のアプリの修正などで、そう簡単にいかない場合もある。
0011デフォルトの名無しさん
2009/09/21(月) 13:03:360012デフォルトの名無しさん
2009/09/21(月) 13:08:43MinGWを使ってWindowsアプリを作った。(NTの話。9xはもうしらねw)
指定されたディレクトリのファイル名一覧を取得。
ファイル名には日本語文字にはないUNICODEが含まれている。
MinGWを使う→Linuxなどでもコンパイルできるソースが目的
なのでWindows APIを直接使うことははばかられた。
まずPOSIX準拠のopendir&readdirを使った。ファイル名を取得した段階ですでに文字化け。
日本語文字以外が ? に変換されてしまった。当たり前のことだろう。
そこで、_wopendir&_wreaddirを使ったらUTF-16LEとしてファイル名を取得できた。
プログラムを全てワイド系関数で書けるのなら、wchar_tとそれ系の関数を使えば解決?
しかし、charを使って書かれているアプリでは大変なことになるかもしれない。
それにwchar_tは扱いが難しそう。
wchar_tを使うときの罠
http://hw001.gate01.com/eggplant/tcf/cpp/wchar_t_trap.html
頼りなさげな wchar_t
http://blog.harapeko.jp/2009/07/25/wchar_t-suck/l
0013デフォルトの名無しさん
2009/09/21(月) 13:09:29じゃあ、あなたはどうやって解決しているんですか?
0014デフォルトの名無しさん
2009/09/21(月) 13:14:58std::wstringが別にある。
海外アプリはchar & std::string 使っているのばっかり。
日本のアプリでも同じような状況か?
なんでだろうか?
0015デフォルトの名無しさん
2009/09/21(月) 13:28:000016デフォルトの名無しさん
2009/09/21(月) 13:34:44つまり、20bitでは104万8576文字分で足りず
21bit必要になる。
wchar_t型だが、VCでは符号無し16bit整数
Linux(GCC)では符号無し32bit整数
つまりVCでは明らかに足りないということになる。
VCではUTF-16LEで格納されるが、UTF-16にはサロゲートペアという
二つあわせて一文字分という機能があり、これで対応している。
つまりWindowsでは、wchar_t一つが一文字とは限らない・・・
Linuxでは楽なのだが。
0017デフォルトの名無しさん
2009/09/21(月) 13:36:15Qtいいよね。Qt Creator(RAD対応IDE)がでてから
格段に作りやすくなった。
最初、てっきりGUI作るだけのツールかと思っていたw
個人で0から作る場合はQt使うと思う。
0018デフォルトの名無しさん
2009/09/21(月) 13:52:01昔の話は置いといて、今の仕様は
UTF-16、エンディアンはシステム依存、サロゲートペア対応らしい。
オライリーの本にはUCS2と書いてあるみたいだけど
サロゲートペア対応ならUTF-16じゃね?
0019デフォルトの名無しさん
2009/09/21(月) 13:55:51つーかUnicodeとUTF-8とUTF-16とUTF-32の違いくらいは最低限知っとけよ…
0020デフォルトの名無しさん
2009/09/21(月) 13:59:36処理系依存だから、UTF-8という実装も
ありかもしれないけど。
0021デフォルトの名無しさん
2009/09/21(月) 14:01:320022デフォルトの名無しさん
2009/09/21(月) 14:01:37> wchar_tっていうだけじゃエンコード(UTF-8なのかUTF-16なのか)がわからない。
のこれのことか
wchar_tっていうだけじゃエンコード(UTF-16LEなのかUTF-32なのか)がわからない。 に
訂正するよ。こまかいことは(ry
0023デフォルトの名無しさん
2009/09/21(月) 14:02:51ぶほっ
0024デフォルトの名無しさん
2009/09/21(月) 14:02:590025デフォルトの名無しさん
2009/09/21(月) 14:04:01いきなりものすげーgdgdだなこのスレw
0026デフォルトの名無しさん
2009/09/21(月) 14:05:59じゃあ、好きなのに変えろよw
本質・・・ wchar_tっていうだけじゃエンコードがわからない。ってのに
変わりは無いだろw
サロゲートペア考慮しないといけない環境と
そうでない環境があるのwchar_tを使うのは
クロスプラットフォームなアプリ作成に置いて、
どうよ?って話をしろ。
0027デフォルトの名無しさん
2009/09/21(月) 14:07:260028デフォルトの名無しさん
2009/09/21(月) 14:10:41しなきゃならないんだから、変換関数で吸収する設計になるんじゃね?
入出力以外は普通にwchar_tでおk
0029デフォルトの名無しさん
2009/09/21(月) 14:16:21どっちの記事もwchar_tに過大な期待をしてるようにしか見えないけど
(特に二番目はUnicodeそのものの理解もかなり怪しげ)、世間的には
このくらい過大な期待をされてるのかもしれんね。
というより、Unicodeそのものが過大な期待をされてる気もするが。
0030デフォルトの名無しさん
2009/09/21(月) 14:19:31wchar_tを使うとして、エンコードは?
0031デフォルトの名無しさん
2009/09/21(月) 14:21:120032デフォルトの名無しさん
2009/09/21(月) 14:21:46ファイル名に関してどうすんの?
0033デフォルトの名無しさん
2009/09/21(月) 14:22:29>>31
0034デフォルトの名無しさん
2009/09/21(月) 14:25:12いや、そうじゃなくてだねw
聞きたいのは、
#ifdef 何のとき?
どんなデータ型でどんな関数を使う?
#else
どんなデータ型でどんな関数を使う?
#endif
って話だよw
0035デフォルトの名無しさん
2009/09/21(月) 14:25:35>>31
0036デフォルトの名無しさん
2009/09/21(月) 14:25:59#ifdef 何のとき?
どんなデータ型でどんな関数を使う?
#else
どんなデータ型でどんな関数を使う?
#endif
(共通部分では)どんなデータ型でどんな関数を使う?
0037デフォルトの名無しさん
2009/09/21(月) 14:27:31UCS-4をそのままぶっこめ
basic_string<uint32_t>
gccならwchar_tにそのまま入るだろ
0038デフォルトの名無しさん
2009/09/21(月) 14:28:27あとはどうにでもなるだろ
wchar_tを使わなくてもできることだが、使ってもできることだし、使わなくても
結局は似たようなことをやる
0039デフォルトの名無しさん
2009/09/21(月) 14:30:00実際どうやっているの?
ってか、やったことあるの?
0040デフォルトの名無しさん
2009/09/21(月) 14:32:20多言語対応でクロスプラットフォームなコードなんてどこで必要なの?
0041デフォルトの名無しさん
2009/09/21(月) 14:38:09あなたに関係の無い世界で必要
0042デフォルトの名無しさん
2009/09/21(月) 14:38:410043デフォルトの名無しさん
2009/09/21(月) 14:40:37読んでないけど
0044デフォルトの名無しさん
2009/09/21(月) 14:44:22お前にも関係ないなw
0045デフォルトの名無しさん
2009/09/21(月) 14:48:110046デフォルトの名無しさん
2009/09/21(月) 18:13:08今風呂掃除をしてついでに風呂に入って、いろいろやってみたら
Linuxではwfopen(_wfopen)が無いらしい。
多言語で問題なのはファイルの中身よりもファイル名の方なんだよね。
中身の処理はアプリ内で完結するけど、ファイル名はOS(ライブラリ)から
渡されたり逆に渡したりしないといけないから
UNICODEが含まれた名前のファイルを開くとき、
Linuxではchar型にUTF-8を入れて、fopenで呼び出す。
Windowsではwchar_t型にUTF-16LEを入れて、wfopenで呼び出す。
いろいろ面倒だなw どちらにしろコード変換処理をなくすことはできないと。
VLCのソースコード見てみたら、utf8_open(utf8_fopen)という関数を作ってあって、
名前のとおり、char型UTF-8をファイル名に指定して、そこでWINなら
パスをUTF-16LEかな?に変換して_wopenを呼び出していたよ。
wchar_tはその変換部分ぐらいにしか使っていなかった。
ちなみに、utf8_opendirなんかもあった。
0047デフォルトの名無しさん
2009/09/21(月) 22:31:14プラットフォーム依存部分で変換することの違いをわかってるのかね
0048デフォルトの名無しさん
2009/09/21(月) 22:40:42君は内部でどう持っているの?
0049デフォルトの名無しさん
2009/09/21(月) 22:47:040050デフォルトの名無しさん
2009/09/21(月) 22:49:06ということは、Windowsのファイル名(UTF-16LE)
Linuxのファイル名(UTF-8 or EUC)は
UTF-32に変換して保持しているの?
変換には何を使ってる?
0051デフォルトの名無しさん
2009/09/21(月) 22:50:55何型使って、UTF-32を保持しているの?
0052デフォルトの名無しさん
2009/09/21(月) 22:52:21頑張ってね!
0053デフォルトの名無しさん
2009/09/21(月) 22:55:55それぐらいの内容は知っているが、
問題は、C/C++でどのようにして使うかという
実践的なところなんだよな。
0054デフォルトの名無しさん
2009/09/22(火) 14:28:260055デフォルトの名無しさん
2009/09/25(金) 18:06:31EUCの2バイトをwchar_tにつっこむシステムは死滅したの?
0056デフォルトの名無しさん
2009/09/25(金) 19:08:49誰に言ってんの?
0057デフォルトの名無しさん
2009/09/26(土) 04:05:14Windowsでは2バイト
Linuxでは4バイト、
しかもUTF-8なんか、1バイト〜4バイトだよ。
どうやって入れれば良いんだよw
0058デフォルトの名無しさん
2009/09/26(土) 13:03:280059デフォルトの名無しさん
2009/09/26(土) 13:49:500060デフォルトの名無しさん
2009/09/26(土) 13:53:400061デフォルトの名無しさん
2009/09/26(土) 14:23:170062デフォルトの名無しさん
2009/09/26(土) 17:00:040063デフォルトの名無しさん
2009/09/29(火) 22:06:02枯れ枯れ性を偏重して進化が遅いっていめーじ。
標準関数に脆弱性があって使わないほうがいいものがあるとか、もうアボガドかと。
0064デフォルトの名無しさん
2009/09/29(火) 23:42:470065デフォルトの名無しさん
2009/09/30(水) 19:33:41あまり実利はないかもね。
0066デフォルトの名無しさん
2009/10/01(木) 13:38:510067デフォルトの名無しさん
2009/10/01(木) 13:45:210068デフォルトの名無しさん
2009/11/30(月) 18:06:18ファイル一覧はwchar_tで取って、ファイルのopenはcharにするのか。
wchar_t -> charはキャストするだけでは駄目だよね。
その部分のコードわかりますか
0069デフォルトの名無しさん
2009/11/30(月) 18:19:16確実に動作しますか。wopendirしないにと駄目な場合がありますか。
windowsでは長いファイル名がとれないとかありますが。
opendirで確実に動くなら、windows側では内部で
wchar_tで動作させて返却すれば善さげですが。
0070デフォルトの名無しさん
2009/11/30(月) 18:25:24wchar_tで\\?\を付けるのはwindowsのみですよね。
0071デフォルトの名無しさん
2009/11/30(月) 18:38:210072デフォルトの名無しさん
2009/11/30(月) 19:13:330073デフォルトの名無しさん
2009/11/30(月) 19:15:51windowsは、パス名に\を含む文字があっても動作するのはなんででしょうか。
char読んだ時点では、区切りか漢字か判別できないはずですが
0074デフォルトの名無しさん
2009/12/01(火) 01:15:51■ このスレッドは過去ログ倉庫に格納されています