2011-04-27 49 views
1

當編組結構包含從C++到C#單個字符字段如何C#結構定義應該看起來像?Marshall結構與char

[StructLayout(LayoutKind.Sequential, Size = 1), Serializable] 
public struct SomeStruct 
{ 
    [MarshalAs(UnmanagedType.I1)] 
    public sbyte Field; 
} 

[StructLayout(LayoutKind.Sequential, Size = 1), Serializable] 
public struct SomeStruct 
{ 
    [MarshalAs(UnmanagedType.U1)] 
    public byte Field; 
} 

我無法找到關於它應該是一個符號字節或沒有一個明確的信息。 (它在C++結構定義中聲明爲'char')

UPD:它取決於C++ lib是使用GCC還是VS(默認編譯器選項)構建?如果沒有,我希望'字符'在GCC和VS上都有簽名(默認編譯選項)

+0

該字段實際上是一個字符,還是它只是其他東西塞進方便的8位類型恰巧被稱爲char? – 2011-04-27 15:32:52

+0

它用於存儲C++中的小整數 – 2011-04-27 15:34:36

回答

3

通常,您不能通過C++判斷char是已簽名還是未簽名。它取決於實現,並且通常可以通過選項來配置單個編譯器(實現),以使其成爲可能。

如果可能,最好的選擇是在C++代碼中明確指出它,即使用signed charunsigned char。然後,您可以根據情況爲C#編組選擇sbytebyte

3

在Visual Studio和GCC中,charsigned by default。可以使用/J編譯器選項(用於GCC的-funsigned-char)使其無符號。

所以答案取決於是否在你的C++項目中使用該選項。

1

答案取決於您更喜歡如何將值存儲在C#中。你應該選擇最方便的。

  • 如果將它作爲無符號值存儲在C#變量中,則將其編組爲UnmanagedType.U1
  • 如果將它作爲有符號值存儲在C#變量中,則將其編組爲UnmanagedType.I1

問題是,一旦該字節跨越模塊邊界,它就是重要的按位表示,而不是C#代碼中的邏輯表示。一旦達到C++代碼,無符號值255就等同於有符號值-1。


當然,這是假設您正在使用char作爲文字種類。在對該問題的評論中,您聲明您將其用作整數類型,在這種情況下,您需要決定是否對其進行簽名和編組。

+0

是的,我明白這一點,似乎我的答案現在只是關於C++ char規範... – 2011-04-27 15:42:29