目次

文字列

C++/CLIの文字列操作は、System::Stringを使います。ソースコード中のリテラル文字列は、必要に応じてString^に格上げされます。内部的にはwchar_t(UTF-16)で値を保持しています。

char*やwchar_t*からString^への変換

const char* p = "AAA";
String^ s = gcnew String(p);

でできます。

String^からwchar_t*への変換

#include <vcclr.h>
 
String^ s = L"AAA";
pin_ptr<const wchar_t> pIn = PtrToStringChars(s);

String^からchar*への変換

String^はユニコードなので変換の際には注意が必要。

StringToHGlobalAnsiを使う

std::string getStdString(String^ s)
{
 std::string ret;
 System::IntPtr pp = System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(s);
 ret = (const char*)pp.ToPointer() ;
 System::Runtime::InteropServices::Marshal::FreeHGlobal(pp);
 return ret;
}

wcstombs_sを使う。locale依存

std::string getStdString(String^ s)
{
	std::string ret;
	if ( s == nullptr )
		return ret;
 
	pin_ptr<const wchar_t> p = PtrToStringChars(s);
	size_t len = (s->Length+1) * sizeof(wchar_t);
	char* pT = (char*)malloc(len);
	size_t retutrnvalue;
 
	if ( 0 != wcstombs_s( &retutrnvalue, 
		pT,
		len,
		p,
		len ) )
	{
		free(pT);
		return ret;
	}
	ret = pT;
	free(pT);
	return ret;
}

Stringの基本事項として、一度設定したら内部の文字列は変化しない(内部の文字列を変更するメソッドはない)があります。これによってあるString^ハンドルによる操作で、たのString^ハンドルの文字列が変化することを心配する必要がなくなります。

また、Stringに対してで暗黙のCLRサポートがあります。

  1. ==で比較すると、ハンドルの比較ではなくて文字列の比較が行われる。!=も同様
  2. +で色々な型を足すことができる。

これら関してはC++との互換性で影響が出ることがあります。

以下のC++コードはC++/CLIだとコンパイルエラーになります。

#include "stdio.h"
int main(int argc, char* argv[])
{
 const char* p = "ABC" + 1;
 printf(p);
 return 0;
}

空文字の扱い

空文字を扱うための仕組みもあるので““やL”“よりもこちらを使うほうがいいかもしれません。

if ( s == nullptr || s->Length == 0 )
    return;

の代わりに

if ( String::IsNullOrEmpty(s) )
    return;

同様に

    return L"";

の代わりに

    return String::Empty;