在 C/C++ 代碼中
以下內容為程序代碼:
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
//
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER
在 C/C++ 中這樣在結構中使用數組是完全正確的
以下內容為程序代碼:
public struct IMAGE_DATA_DIRECTORY
{
public uint VirtualAddress;
public uint Size;
}
public struct IMAGE_OPTIONAL_HEADER
{
public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
public ushort Magic;
//
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
在 C# 中這樣定義結構中的數組是錯誤的
以下為引用
error CS
如果改用 C# 中引用類型的類似定義語法
以下內容為程序代碼:
public struct IMAGE_OPTIONAL_HEADER
{
public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
public ushort Magic;
//
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY[] DataDirectory = new IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
則得到一個 CS
以下為引用
error CS
因為結構內是不能夠有引用類型的初始化的
以下內容為程序代碼:
public struct IMAGE_OPTIONAL_HEADER
{
public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
public ushort Magic;
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY[] DataDirectory;
public IMAGE_OPTIONAL_HEADER(IntPtr ptr)
{
Magic =
NumberOfRvaAndSizes =
DataDirectory = new IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
}
這樣一來看起來似乎能使了
於是問題就變成如何將引用類型的數組
解決的方法有很多
以下內容為程序代碼:
[StructLayout(LayoutKind
public struct IMAGE_OPTIONAL_HEADER
{
public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
public ushort Magic;
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY DataDirectory;
}
注意這兒 StructLayout 中 Size 指定的是整個結構的長度
這種方法的優點是定義簡單
另外一種解決方法是通過 Marshal 的支持
以下內容為程序代碼:
[StructLayout(LayoutKind
public struct IMAGE_OPTIONAL_HEADER
{
public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
public ushort Magic;
public uint NumberOfRvaAndSizes;
[MarshalAs(UnmanagedType
public IMAGE_DATA_DIRECTORY[] DataDirectory;
}
這種方法相對來說要優雅一些
以下內容為程序代碼:
雖然類型還是 valuetype IMAGE_DATA_DIRECTORY[]
除了上述兩種在結構定義本身做文章的解決方法
此類結構除了對結構內數組的訪問外
以下內容為程序代碼:
[Serializable]
public struct IMAGE_OPTIONAL_HEADER : ISerializable
{
public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
public ushort Magic;
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY[] DataDirectory;
public IMAGE_OPTIONAL_HEADER(IntPtr ptr)
{
Magic =
NumberOfRvaAndSizes =
DataDirectory = new IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
[SecurityPermissionAttribute(SecurityAction
public virtual void GetObjectData(SerializationInfo info
{
// 完成序列化操作
}
}
這種解決方法可以將結構的載入和存儲
與此思路類似的是我比較喜歡的一種解決方法
以下內容為程序代碼:
public class IMAGE_OPTIONAL_HEADER : BinaryBlock
{
public const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
public ushort Magic;
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY[] DataDirectory = new IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
注意原本的 struct 在這兒已經改為 class
以下內容為程序代碼:
public class BinaryBlock
{
private static readonly ILog _log = LogManager
public BinaryBlock()
{
}
static public object LoadFromStream(BinaryReader reader
{
if(objType
{
return reader
}
else if(objType
{
return reader
}
//
else if(objType
{
return reader
}
else if(objType
{
// 處理數組的情況
}
else
{
foreach(FieldInfo field in Cla
From:http://tw.wingwit.com/Article/os/youhua/201311/10867.html