C++/CLIでSystem::String^文字列をchar*に変換する関数の改良方法

このQ&Aのポイント
  • C++/CLIでSystem::String^文字列をchar*に変換する関数を改良する方法について解説します。
  • 現在の関数では256文字以上の文字列を変換する際に問題が発生しています。改良することでこの制限を解決できます。
  • 提供された関数を改良し、256文字以上の文字列を正しく変換できるようにする方法を紹介します。
回答を見る
  • ベストアンサー

System::String->char*変換でき

C++/CLIでSystem::String^文字列をchar*に変換する関数を書いたのですが、256文字以上の文字列を投げて、戻値を確認してみると、255文字分しか中身が詰まっていません。元の文字列はアスキーのみです。 #include <msclr/marshal.h> using namespace msclr::interop; static char* toPtChar(const String^ Text) { String^ temp = (String^)Text; msclr::interop::marshal_context^ context = gcnew msclr::interop::marshal_context(); char* res = ((char*)(context->marshal_as<const char*>(temp))); return res; } この関数をどのように変更すれば、256文字以上変換できるでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

L"..." はワイド文字列(Unicode) marshalライブラリの使い方は参考URLに。

参考URL:
http://codezine.jp/article/detail/4774
sumire_kanou
質問者

お礼

何度もありがとうございます。 これまで文字列の中身をVSのテキストビジュアライザで確認していました。String^の内容をそれで確認すると、256文字以上表示されていたのですが、char*の中身を表示してみると255文字以下に切り捨てられていました。そこで、もしやと思いchar*の中身をstdoutに吐いてみると、256文字以上表示されていました。どうも文字列サイズを持っていないchar*を表示する際に、暗黙下に255文字+\0に丸めているようです…。ちょっと調べてもそのような仕様は見つかりませんでしたが、「安全の為」と言いつつ、勝手に誤解を招く挙動を平気でやってくれるのはいつものことですし、きっとそういう仕様なんでしょう。 お騒がせして申し訳ありません。また少し、マイクロソフトが嫌いになれました。

その他の回答 (1)

回答No.1

↓問題ないっすねー (VC++10) #include <iostream> #include <msclr/marshal.h> using namespace msclr::interop; using namespace std; using namespace System; int main() { String^ input = L""; for ( int i = 0; i < 100; ++i ) { input = input + L"0123456789"; } marshal_context ctx; // キモはココと const char* result = ctx.marshal_as<const char*>(input); // ココだけ cout << result << endl; }

sumire_kanou
質問者

補足

ありがとうございます。C++/CLI初心者の為、L"~"が理解できていないですが、文字列の型指定子みたいなものでしょうか? あと、私が提示しましたコードのようにString^として受け取り(L""を結合して生成しない)char*として返す(標準出力に吐かない)関数は、そちらでもちゃんと動作していますでしょうか?書き忘れてしまいましたが、当方VC++2008です。 C#アプリとアンマネージドC++DLLのラッパDLL(C++/CLI)として、文字列変換が必要になっています。この関数に入った時点ではTextはちゃんと256文字以上なので、DLL間で欠落していないと思いますが…

関連するQ&A

  • System::Stringからconst charへの変換

    aという変数がSystem::String型であります。 そこで次に行いたい処理のために、const char*に変換したいのですが、下記のページを参考にプログラムしてみたのですがうまくいきませんでした。 うまくいかなかったというのはまだSystem::String型のままで変換できていなかったとエラーで出てしまいます。 そのような場合は、どのように型変換すればよいのでしょうか?

  • String型をchar型配列にしたい

     VC++2005ExpressEdition + PlatformSDKを使用しています.  String型をchar型配列に変換したいと思っています.  自分なりに調べてみたのですが, > String^ str = gcnew String("test"); > char chr[5]; > chr = str->ToCharArray(); などとしても次のようなエラーが出ます. > error C2440: '=' : 'cli::array<Type,dimension> ^' から 'char [5]' に変換できません。  String型からchar型配列への変換はどのようにすればいいのでしょうか.

  • char型とstring型について

    char型とstring型について質問があります。 言語はC++です。 以下の関数があったとします。 void test(string a, string b string c){ 処理 } この関数を下記のように利用した場合について質問があります。 a.引数に直接文字列を挿入したケース test("aaa","bbb","ccc") b.変数に文字列を設定し、変数を引数にしたケース string a="aaa" string b="bbb" string c="ccc" test(a,b,c) (1)はコンパイルエラーになり、(2)は成功しました。 同じ様に見えるのですが、何が違うのでしょうか? また、関数の引数の型をchar*にした場合、(1)(2)のケースでコンパイルが通りました。char*型だと何が違うのでしょうか?

  • unsigned char SJis[2]からstd::stringに変換

    開発環境は VC++ 2008 Express Edition あるDLLの関数で戻り値としてShiftJISの1文字が格納された unsigned char SJis[2] が返され,これを呼び出し側のプログラムで使っている文字列 std::string str に順に追加していこうと思っています. そこで, unsigned char tmpSJis[3]; tmpSJis[0] = SJis[0]; tmpSJis[1] = SJis[1]; tmpSJis[2] = '\0'; str += std::string(tmpCode); というコードを書いてループさせたのですが, error C2440: '<function-style-cast>' : 'unsigned char *' から 'std::string' に変換できません。 というエラーが出てしまいうまく変換できません. これを解決する方法はありませんか?

  • String型からChar配列への変換は可能?

    String型から例えばcharの配列に変換するという事はできるでしょうか String str="OKwave"だとすると char c[]={'O','K','w','a'.'v','e'}; というような感じにしたいのですが、流石に不可能でしょうか。 もし出来ないなら、代替方法とか教えていただけるとありがたいです。 とりあえず、文字を一つ一つに分けたいのです・・・ Javaはまだ初心者で、質問内容も初歩的なものだと思いますが、よろしくおねがいします。

    • ベストアンサー
    • Java
  • DWORDとcharの変換

    突然ですが、DWORD*がたの文字列をchar*がたの文字列に変換する方法ってありますか? あれば関数名など教えていただけると助かります。 いそいでいます。お願いしますm(_ _)m

  • VC String型のエンディアン変換

    お世話になります String型の文字列のそれぞれの文字(一文字ずつ)の エンディアンを変更したいのですが、簡単な方法はないでしょうか? 今考えている方法は Stringから一文字ずつcharに入れ込んで このcharをシフトとマスクで入れ替える方法なのですが ((val<<8) & 0xff00) | ((val>>8) & 0x00ff) エンディアン変換の前後でString⇒charとchar⇒Stringを行うので、 少し煩雑になるのが気になっております。 型変換無しでエンディアン変換できないでしょうか

  • char型配列をString型にしたい

     VC++2005ExpressEdition + PlatformSDKを使用しています.  char型配列をString型にしたいと思っています(MessageBoxで表示するため).  int型ならば, > String^ out = String::Format("{0}", i ); > MessageBox::Show(out); などとできます.  下のアドレス(*1)のNo.2の答えにあるように > char ss[256]; > String^ out; > out=ss; とすると > error C2440: '=' : 'char [128]' から 'System::String ^' に変換できません。 なるエラーが出ます(S を大文字にしたりハットを付けたりしています).  char型の配列のString型への変換はどのようにすればいいのでしょうか. (*1)http://oshiete1.goo.ne.jp/kotaeru.php3?q=479640

  • VC++2010で配列に文字列を使用する方法

    array<String^,3>^ myMat = gcnew array<String^,3>(15,97,3338); このようにするとビルド出来るのですが、 array<String^,3>^ myMat = gcnew array<String^,3>("あ","か","さ"); とすると 1>d:\documents and settings\****\my documents\visual studio 2010\projects\****\Form1.h(220): error C2440: '初期化中' : 'const char [3]' から 'int' に変換できません。 1> この変換が可能なコンテキストはありません。 とエラーが出てしまいます どのようにすれば良いのでしょうか?

  • String型とchar型の変換エラーです

    今晩は!またまたこの掲示板にきました。よろしくお願いします。 文字列かブランクを取り出すコードを書きましたが、 -------- char ch_check = str.charAt(i+1) ; if(ch_check ==" ") { --------- のところでString型とchar型の混合は受け入れられませんのようなエラーが出ました。 if(ch_check ==" "をboolean型でうけるのも拒否されました。 どこをどのようにしてやればよいでしょうか。 JAVA初心者です、特に文字列の取り扱いは評判通りわかり難くくないています。 よろしくお願いします。 ---------- public class Mojiretu_Blank { public static void main(String[] args) { String str = "This is a pen."; int i = 1 ; int blank_count = 0 ; while( i < (str.length()+1) ) { char ch_check = str.charAt(i+1) ; if(ch_check ==" ") { blank_count ++ ; System.out.println(ch_check); } else{} System.out.print("ブランクの数は" + blank_count + "個です。"); } } }

    • ベストアンサー
    • Java