2011-07-11 48 views
2

是否有一種直接的方法來管理包裝器中的C++/CLI字符串以用於本地C++方法的char *參數?System ::字符串引用C++ char *參數

例如:

void Test::TestFunc(System::String ^%str) 
{ 
    // right conversion to char* and consider the reference 
} 

本地C++函數:

void TestB::Func(char *str) 
{ 
    ... 
} 

我取巧的辦法:

void Test::TestFunc(System::String ^%szRecvBuffer) 
{ 
    pin_ptr<const wchar_t> szRecvBufferP = PtrToStringChars(szRecvBuffer); 

    // Convert to a char* 
    size_t origsize = wcslen(szRecvBufferP) + 1; 
    const size_t newsize = 100; 
    size_t convertedChars = 0; 
    char nstring[newsize]; 
    wcstombs_s(&convertedChars, nstring, origsize, szRecvBufferP, _TRUNCATE); 
    strcat_s(nstring, " (char *)"); 

    char *szRecvBufferCh = nstring; 

    m_object->TestCommand(szRecvBufferCh); // parameter char* 
    System::String ^tmp = gcnew System::String(szRecvBufferCh); 
    szRecvBuffer = tmp; 
} 

迎接leon22

回答

2

你正在做很多手工操作,運行時會爲你照顧。

void Test::TestFunc(String^% szRecvBuffer) 
{ 
    using System::Runtime::InteropServices::Marshal; 

    IntPtr memHandle = Marshal::StringToHGlobalAnsi(szRecvBuffer); 
    try 
    { 
     char* const str = static_cast<char*>(memHandle.ToPointer()); 
     m_object->TestCommand(str); 
     szRecvBuffer = gcnew String(str); 
    } 
    finally 
    { 
     Marshal::FreeHGlobal(memHandle); 
    } 
} 

如果您在使用VC++ 2010,您可以使用std::unique_ptr<>與定製刪除,以避免使用try..finally,最終削減一半的代碼行數。

0

如果你搜索「系統::字符串「與谷歌,我的第二個鏈接s How to convert from System::String* to Char* in Visual C++。這顯然是一個常見問題!

(似乎有根據需要轉換的細節在5個不同的方式,所以我不會在這裏總結一下他們:去閱讀文章。)

+0

是的,我知道這篇文章。但是,你將如何處理引用(需要將函數的答案寫入字符串中) - >和我的棘手方式相同? – leon22

+0

在這種情況下,我超出了我的CLI深度!我不得不承認,我不太理解你的問題:「需要函數的答案到字符串中」不會爲我解析。 –

2

如果char*是輸出參數,然後在C++/CLI中,你必須通過System::StringBuilder^

+0

請您描述一下,請! – leon22

+1

@Armen:這對於P/Invoke來說是正確的,但是我沒有在OP的代碼中看到任何P/Invoke簽名,並且從C++/CLI使用P/Invoke會非常愚蠢。 – ildjarn

0

不能避免在兩個方向上的轉換,因爲System::String使用wchar_t和Unicode的>多字節轉換是必要的,以獲得從char

但是marshal_as應該使轉換更容易。

+0

我不認爲'marshal_context'是專門爲'char *'提供的,只有'char const *',但它肯定是微不足道的寫一個 – ildjarn