簡體   English   中英

C ++:本地到托管字符串轉換問題(也許是字符集)?

[英]C++: Native to Managed String Conversion Problem (Maybe Character Set)?

我在以正確的字符集返回本地字符串時遇到問題。 我將字符串從wstring轉換為LPCWSTR以傳遞回托管。 對於從字符串到寬字符串, s2ws方法產生的字符串返回非常小,因為它似乎停止在我的第一個可能的終止符(在托管方式中),即“;”。 因此,在您提到s2ws之前,我已經嘗試了一下,但沒有成功。

字符串內容:

    char target[1024];
    sprintf_s(target, 1024, "%s %s%s%s",
            mac,
            " (",
            pWLanBssList->wlanBssEntries[t].dot11Ssid.ucSSID,
            ");");
    std::string targetString = std::string(target);
    targetWString.append(targetString.begin(), targetString.end());

后來的字符串:

std::wstring returnWString = L"";
returnWString.append(SomeMthod().c_str());
//wprintf_s(returnWString.c_str()); // Works - Data is in the string.
LPCWSTR returnLpcuwstr = returnWString.c_str();
return returnLpcuwstr;

我怎么知道這是一個字符集/編碼問題? 好吧,當LPCWSTR返回到托管狀態並且我使用Marshal轉換為Unicode字符串時,我得到了一排空/空字符。 當我在ANSI中嘗試時,這就是我得到的(減小了大小/比例的可讀性):

ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ

s2ws方法應該解決std :: string-> std :: wstring的ANSI / UNICODE噩夢,但這會使返回值太短-比它應該的短得多-但不能解決實際的字符集問題。

結果(再次達到ANSI-我未做任何還原):

當我檢查本機時, wprintf_s向我顯示在導出方法中發生LPCWSTR轉換之前,該字符串有效/良好; 因此,我需要了解:

  1. 有沒有辦法讓我知道字符的字節大小實際是多少? (我認為這是8字節還是16字節的情況?)
  2. 由於wprintf_s在寬字符串上起作用,因此我根據LPCWSTR對其進行了檢查,並打印了相同(預期)的數據。 因此,問題似乎不在LPCWSTR的.ctor()中。 但是,我想仔細檢查一下數學:我LPCWSTR是否正確?
  3. 既然native的所有內容都告訴我字符串是好的,那么如何檢查它的字符集(在native中)?

返回值本身大約是8行文本,帶有定界符';'。 用於將字符串拆分為托管字符串並對其進行魔術處理。 唯一的問題是讓字符串以托管的形式呈現為有效字符串,其中包含正確的字符。

我覺得,也許是,我在這里遺漏了一些明顯的東西,但是我無法弄清楚它是什么,只需要換一雙新的眼睛來告訴我我在哪里以及如何生活會失敗。

LPCWSTR returnLpcuwstr = returnWString.c_str();
return returnLpcuwstr;

returnWString超出范圍時,這將返回一個指向在return之后立即釋放的數據的指針。 返回的指針在接收者甚至可以使用它之前是無效的。 這是未定義的行為

要執行您要嘗試的操作,您將必須返回指向動態分配的內存的指針,然后接收器在使用完該內存后必須釋放該內存。

假設您使用的是“托管”,則指的是.NET,然后.NET的編組者使用CoTaskMemFree()釋放非托管內存,因此,如果您使用默認的封送處理,則返回的指針必須指向使用CoTaskMemAlloc()或等效的分配的內存( SysAllocString...() ,例如)。

否則,如果您沒有使用默認的封送處理(即,您手動調用Marshal.PtrToStringUni() ),那么您將必須使.NET代碼將內存指針傳遞回C ++代碼,以便隨后可以釋放內存正常。 然后,您的C ++代碼可以根據需要分配內存(只要仍動態分配內存,這樣它就可以在函數返回后繼續存在)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM