非托管结构体中定义固定大小的数组问题

Eastunfail 2005-04-15 11:54:34
假设某个API需要用到某个结构,而那个结构中包含一个固定大小的数组,如:
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;

//
// NT additional fields.
//

DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;


我要写C#中对应的代码该如何呢?

[StructLayout(LayoutKind.Sequential)]
public struct ImageOptionalHeader
{
//Standard Field.
UInt16 Magic;
Byte MajorLinkerVersion;
Byte MinorLinkerVersion;
UInt32 SizeOfCode;
UInt32 SizeOfInitializedData;
UInt32 SizeOfUninitializedData;
UInt32 AddressOfEntryPoint;
UInt32 BaseOfCode;
UInt32 BaseOfData;
//NT Additional fields
UInt32 ImageBase;
UInt32 SectionAlignment;
UInt32 FileAlignment;
UInt16 MajorOperatingSystemVersion;
UInt16 MinorOperatingSystemVersion;
UInt16 MajorImageVersion;
UInt16 MinorImageVersion;
UInt16 MajorSubsystemVersion;
UInt16 MinorSubsystemVersion;
UInt32 Win32VersionValue;
UInt32 SizeOfImage;
UInt32 SizeOfHeaders;
UInt32 CheckSum;
UInt16 Sybsystem;
UInt16 DllCharacteristics;
UInt32 SizeOfStackReserve;
UInt32 SizeOfStackCommit;
UInt32 SizeOfHeapReserve;
UInt32 SizeOfHeapCommit;
UInt32 LoaderFlags;
UInt32 NumberOfRvaAndSizes;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=16,ArraySubType=UnmanagedType.Struct )]
ImageDataDirectory[] DataDirectory;
}

能通过编译但是无法通过sizeof获取大小。说这个是托管类型。而没有定义数组的结构却可以通过sizeof获取大小。

怎么能修改这个ImageOptionalHeader让他能通过sizeof获取正确的大小呢?
...全文
559 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
速马 2005-04-23
  • 打赏
  • 举报
回复
http://blog.sunmast.com/sunmast/archive/2005/04/19/1739.aspx
Eastunfail 2005-04-23
  • 打赏
  • 举报
回复
这些方法还是好别扭,还是等2.0吧。。。。。
速马 2005-04-22
  • 打赏
  • 举报
回复
嗯我似乎找到答案了:
http://www.dotnet247.com/247reference/msgs/29/147905.aspx

看来我的推测没错(连解决方案都类似)
Eastunfail 2005-04-22
  • 打赏
  • 举报
回复
谢谢各位高手.

不过他们的代码能够正常运行么?我这里就算直接Copy & Paste他们的代码,运行时也会产生那个异常
速马 2005-04-17
  • 打赏
  • 举报
回复
嗯那个帖子我也搜索到了
不过那个人问的最后一个问题似乎没有人回答...
蒋晟 2005-04-17
  • 打赏
  • 举报
回复
http://ng.csharpfriends.com/top/ng/group~1/~42784~__Class-struct-and-Marshal_SizeOf/index.aspx
速马 2005-04-17
  • 打赏
  • 举报
回复
我现在觉得这是Marshal.SizeOf的一个限制,原生类型的数组才可以被支持
不如这样绕过这个问题:

[StructLayout(LayoutKind.Sequential)]
public struct ImageDataDirectory
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
UInt32[] Data;
}

[StructLayout(LayoutKind.Sequential)]
public struct ImageOptionalHeader
{
//Standard Field.
UInt16 Magic;
Byte MajorLinkerVersion;
Byte MinorLinkerVersion;
UInt32 SizeOfCode;
UInt32 SizeOfInitializedData;
UInt32 SizeOfUninitializedData;
UInt32 AddressOfEntryPoint;
UInt32 BaseOfCode;
UInt32 BaseOfData;
//NT Additional fields
UInt32 ImageBase;
UInt32 SectionAlignment;
UInt32 FileAlignment;
UInt16 MajorOperatingSystemVersion;
UInt16 MinorOperatingSystemVersion;
UInt16 MajorImageVersion;
UInt16 MinorImageVersion;
UInt16 MajorSubsystemVersion;
UInt16 MinorSubsystemVersion;
UInt32 Win32VersionValue;
UInt32 SizeOfImage;
UInt32 SizeOfHeaders;
UInt32 CheckSum;
UInt16 Sybsystem;
UInt16 DllCharacteristics;
UInt32 SizeOfStackReserve;
UInt32 SizeOfStackCommit;
UInt32 SizeOfHeapReserve;
UInt32 SizeOfHeapCommit;
UInt32 LoaderFlags;
UInt32 NumberOfRvaAndSizes;
ImageDataDirectory DataDirectory;
}

这样Marshal.SizeOf输出224,和C++的一样,内存里也应该可以对应
除了操作ImageDataDirectory时得麻烦一点了

我也找不到解决办法嗯
这个实在是没有道理,因为UInt32也是个结构体
Eastunfail 2005-04-16
  • 打赏
  • 举报
回复
可参考 Vc7\PlatformSDK\include\WinNT.h 之
IMAGE_FILE_HEADER
IMAGE_DATA_DIRECTORY
IMAGE_OPTIONAL_HEADER
Eastunfail 2005-04-16
  • 打赏
  • 举报
回复
Code:


using System;
using System.Runtime.InteropServices ;


namespace PELibrary
{


/// <summary>
/// At the beginning of an object file, or immediately after the signature of an image file,
/// there is a standard COFF header of the following format.
/// Note that the Windows NT loader limits the Number of Sections to 96.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ImageFileHeader
{
/// <summary>
/// Number identifying type of target machine.
/// </summary>
UInt16 Machine;
/// <summary>
/// Number of sections; indicates size of the Section Table, which immediately follows the headers.
/// </summary>
UInt16 NumberOfSections;
/// <summary>
/// Time and date the file was created.
/// </summary>
UInt32 TimeDateStamp;
/// <summary>
/// File offset of the COFF symbol table or 0 if none is present.
/// </summary>
UInt32 PointerToSymbolTable;
/// <summary>
/// Number of entries in the symbol table. This data can be used in locating the string table, which immediately follows the symbol table.
/// </summary>
UInt32 NumberOfSymbols;
/// <summary>
/// Size of the optional header, which is required for executable files but not for object files. An object file should have a value of 0 here. The format is described in the section “Optional Header.”
/// </summary>
UInt16 SizeOfOptionalHeader;
/// <summary>
/// Flags indicating attributes of the file. for specific flag values.
/// </summary>
UInt16 Characteristics;
}

[StructLayout(LayoutKind.Sequential)]
public struct ImageOptionalHeader
{
//Standard Field.
UInt16 Magic;
Byte MajorLinkerVersion;
Byte MinorLinkerVersion;
UInt32 SizeOfCode;
UInt32 SizeOfInitializedData;
UInt32 SizeOfUninitializedData;
UInt32 AddressOfEntryPoint;
UInt32 BaseOfCode;
UInt32 BaseOfData;
//NT Additional fields
UInt32 ImageBase;
UInt32 SectionAlignment;
UInt32 FileAlignment;
UInt16 MajorOperatingSystemVersion;
UInt16 MinorOperatingSystemVersion;
UInt16 MajorImageVersion;
UInt16 MinorImageVersion;
UInt16 MajorSubsystemVersion;
UInt16 MinorSubsystemVersion;
UInt32 Win32VersionValue;
UInt32 SizeOfImage;
UInt32 SizeOfHeaders;
UInt32 CheckSum;
UInt16 Sybsystem;
UInt16 DllCharacteristics;
UInt32 SizeOfStackReserve;
UInt32 SizeOfStackCommit;
UInt32 SizeOfHeapReserve;
UInt32 SizeOfHeapCommit;
UInt32 LoaderFlags;
UInt32 NumberOfRvaAndSizes;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=16,ArraySubType=UnmanagedType.Struct )]
ImageDataDirectory[] DataDirectory;
}

[StructLayout(LayoutKind.Sequential)]
public struct ImageDataDirectory
{
UInt32 VirtualAddress;
UInt32 Size;
}

}
速马 2005-04-16
  • 打赏
  • 举报
回复
贴出你的ImageDataDirectory结构定义,和内存对齐的相关指令
苹果软件 2005-04-16
  • 打赏
  • 举报
回复
vb.net中怎么封送二维的结构数组呀!请教。。。
Eastunfail 2005-04-16
  • 打赏
  • 举报
回复
没用。赫赫。能通过编译,但有运行时的异常
Eastunfail 2005-04-16
  • 打赏
  • 举报
回复
速马 2005-04-16
  • 打赏
  • 举报
回复
试一下Marshal.SizeOf(typeof(ImageOptionalHeader))嗯
Eastunfail 2005-04-16
  • 打赏
  • 举报
回复
yeah~~~ in C#, with unsafe keyword

maybe I should change another method to perform it.
It seems it's impossible to get the real size of the structure that contains a structure array, based on my testing in Delphi.net, Managed C++, VB.NET and C#
saucer 2005-04-16
  • 打赏
  • 举报
回复
>>>能通过编译但是无法通过sizeof获取大小。说这个是托管类型。

>>>而没有定义数组的结构却可以通sizeof获取大小。

where are you using sizeof? in C#? unsafe mode? if it is a 托管类型, have you tried
DataDirectory.Length?
Eastunfail 2005-04-16
  • 打赏
  • 举报
回复
up
Eastunfail 2005-04-15
  • 打赏
  • 举报
回复
看了一下SharpAssembly的代码。他并没有通过结构体来获取这些数据,而是每个ImageDataDirectory调用两次 binaryReader.ReadUInt32()来获取的

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧