Visual C++ Express 2005 Beta2で、managedコンソールアプリケーションのテンプレートでプロジェクト作成後に、以下のソースを入力します。
#include "stdafx.h"
// あえてprintfを使うのincludeしておく
#include <stdio.h>
using namespace System;
// ここからはネイティブコードにしてちょ
#pragma unmanaged
// printfでcharのポインタで受けた文字列を出力するネイティブコード関数
void unmanagedOutput(const char * str)
{
printf("native string: %s\n",str);
}
// いかにも古き良きCらしいコーディングで文字列を生成するネイティブコード関数
// むろん、以下の関数はバッファオーバーランの可能性がある悪い関数である
void unmanagedCreateString(char * str)
{
// 要するにアルファベット大文字A~Zの生成
for( int i=0; i<26; i++ )
{
*str++ = 'A' + i;
}
*str = '\0';
}
// ここからはmanagedコードに戻してちょ
#pragma managed
// managedコードで文字列を加工する関数。小文字にしてみる
String ^ managedModefyString( String ^ str )
{
return str->ToLower();
}
int main(array<System::String ^> ^args)
{
// 入れ物になる配列。マジックナンバー27はお行儀が悪いぞ!
char test[27];
// ネイティブコード関数で配列に文字列をセットさせる
unmanagedCreateString(test);
// managedコードで文字列を加工する
// char配列からSystem::Stringに直すのは、
// System::Stringのコンストラクタに任せればおしまい
String ^ result = managedModefyString( gcnew String(test) );
// あえてSystem::Stringの文字列をシフトJISの文字列に戻してもらう
// 結果はunsigned char型のmanagedな配列になる
array<unsigned char> ^ arrayResult = System::Text::Encoding::GetEncoding("Shift_JIS")->GetBytes(result);
// charの配列に中身をコピー
char * nativeResult = new char[arrayResult->Length+1];
for( int i=0; i<arrayResult->Length; i++ )
{
nativeResult[i] = arrayResult[i];
}
nativeResult[arrayResult->Length] = '\0';
// ネイティブコード関数から結果を出力
unmanagedOutput(nativeResult);
// おっと、後始末を忘れちゃいけません!
delete nativeResult;
// おしまい
return 0;
}
勝手知ったるC++と勝手知ったる.NET Frameworkクラスライブラリであるはずなのに、微妙に苦労が絶えません。すりあわせ部分の整合性が綺麗に噛み合っていない感じです。しかし、すりあわせそのものは難しい処理ではないので、汎用ライブラリ化も容易でしょう。たぶん、マーシャリング関係にそういう便利な機能も揃っているに違いないと考えて、もうちょっとスマートに書けないか試行を続けてみましょう。