2

ここで C++ と C# の通信に関する質問をしました。問題は解決しましたが、新たな問題が発生しました。

これは文字列を返します (C#)

return Marshal.PtrToStringAnsi(decryptsn(InpData));

これは TCHAR* (C++) を想定しています

lpAlpha2[0] = Company::Pins::Bank::Decryption::Decrypt::Decryption("123456");

この問題を解決する方法をグーグルで検索しましたが、文字列にニンジン(^)が付いている理由がわかりません。戻り値を String から C++ が受け入れる別のものに変更するのが最善でしょうか? または、値を割り当てる前に変換を行う必要がありますか?

4

3 に答える 3

5

^これはマネージド参照のマーカーであるため、文字列には があります。基本的には、管理されていない土地と同じように使用され*ますが、オブジェクト型のみを指すことができ、他のポインター型や void を指すことはできません。

TCHAR_UNICODE プリプロセッサ定義に基づいて、charまたはのいずれかに #defined (または、おそらく typedefed、覚えていません)です。wchar_tしたがって、それを使用してコードを 2 回記述します。

インラインのいずれか:

TCHAR* str;
String^ managedString
#ifdef _UNICODE
str = (TCHAR*) Marshal::StringToHGlobalUni(managedString).ToPointer();
#else
str = (TCHAR*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
#endif

// use str.

Marshal::FreeHGlobal(IntPtr(str));

どちらも、出力バッファーが既に割り当てられており、十分な大きさがあることを前提としています。メソッドのオーバーロードは、TCHAR の定義に基づいて、正しいメソッドを選択する必要があります。

void ConvertManagedString(String^ managedString, char* outString)
{
    char* str;
    str = (char*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();    
    strcpy(outString, str);    
    Marshal::FreeHGlobal(IntPtr(str));
}

void ConvertManagedString(String^ managedString, wchar_t* outString)
{
    wchar_t* str;
    str = (wchar_t*) Marshal::StringToHGlobalUni(managedString).ToPointer();    
    wcscpy(outString, str);    
    Marshal::FreeHGlobal(IntPtr(str));
}
于 2011-04-14T17:37:18.037 に答える
4

構文String^は、「System.String への (ガベージ コレクション) 参照」の C++/CLI トークです。

Stringを表現する別の方法である C 文字列への a の変換には、いくつかのオプションがありますTCHAR*。C++ での私の好みの方法は、プロジェクトを Unicode または MBCS プロジェクトとしてビルドするかstd::wstringどうかに応じて、変換された文字列を C++ 文字列型 ( または ) に格納することです。std::string

どちらの場合でも、次のようなものを使用できます。

std::wstring tmp = msclr::interop::marshal_as<std::wstring>( /* Your .NET String */ );

また

std::string tmp = msclr::interop::marshal_as<std::string>(...);

文字列を正しいワイド文字列またはナロー文字列形式に変換したら、次のc_str()ように関数を使用してその C 文字列表現にアクセスできます。

callCFunction(tmp.c_str());

コンパイル設定に応じて「劣化」するC スタイルのor (これcallCFunctionを渡すことを期待していると仮定します。char*wchar_t*TCHAR*

于 2011-04-14T17:24:14.667 に答える
2

これは質問をするのに非常にとりとめのない方法ですが、 aString ^を aに変換する方法を意味する場合char *は、以前に使用したのと同じマーシャラーを逆方向にのみ使用します。

char* unmanagedstring = (char *) Marshal::StringToHGlobalAnsi(managedstring).ToPointer();

編集: を使い終わったら、割り当てられたメモリを解放することを忘れないでくださいMarshal::FreeHGlobal

于 2011-04-14T17:21:26.527 に答える