C++ Union в C#
Формулировка задачи:
Здравствуйте!
Пишу программу на C# и столкнулся с проблемой, что dll написанная на с++ и использует Union структуру.
Помогите, пожалуйста, написать данную структуру на C#.
union wimlib_progress_info {
struct wimlib_progress_info_write_streams {
uint64_t total_bytes;
uint64_t total_streams;
uint64_t completed_bytes;
uint64_t completed_streams;
uint32_t num_threads;
int32_t compression_type;
uint32_t total_parts;
uint32_t completed_parts;
} write_streams;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN,
* ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY, and
* ::WIMLIB_PROGRESS_MSG_SCAN_END. */
struct wimlib_progress_info_scan {
/** Top-level directory being scanned; or, when capturing an NTFS
* volume with ::WIMLIB_ADD_FLAG_NTFS, this is instead the path
* to the file or block device that contains the NTFS volume
* being scanned. */
const wimlib_tchar *source;
/** Path to the file (or directory) that has been scanned, valid
* on ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY. When capturing an NTFS
* volume with ::WIMLIB_ADD_FLAG_NTFS, this path will be
* relative to the root of the NTFS volume. */
const wimlib_tchar *cur_path;
/** Dentry scan status, valid on
* ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY. */
enum {
/** File looks okay and will be captured. */
WIMLIB_SCAN_DENTRY_OK = 0,
/** File is being excluded from capture due to the
* capture configuration. */
WIMLIB_SCAN_DENTRY_EXCLUDED = 1,
/** File is being excluded from capture due to being of
* an unsupported type. */
WIMLIB_SCAN_DENTRY_UNSUPPORTED = 2,
/** The file is an absolute symbolic link or junction
* that points into the capture directory, and
* reparse-point fixups are enabled, so its target is
* being adjusted. (Reparse point fixups can be
* disabled with the flag ::WIMLIB_ADD_FLAG_NORPFIX.)
*/
WIMLIB_SCAN_DENTRY_FIXED_SYMLINK = 3,
/** Reparse-point fixups are enabled, but the file is an
* absolute symbolic link or junction that does
* <b>not</b> point into the capture directory, so its
* target is <b>not</b> being adjusted. */
WIMLIB_SCAN_DENTRY_NOT_FIXED_SYMLINK = 4,
} status;
union {
/** Target path in the image. Only valid on messages
* ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and
* ::WIMLIB_PROGRESS_MSG_SCAN_END. */
const wimlib_tchar *wim_target_path;
/** For ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY and a status
* of @p WIMLIB_SCAN_DENTRY_FIXED_SYMLINK or @p
* WIMLIB_SCAN_DENTRY_NOT_FIXED_SYMLINK, this is the
* target of the absolute symbolic link or junction. */
const wimlib_tchar *symlink_target;
};
/** The number of directories scanned so far, not counting
* excluded/unsupported files. */
uint64_t num_dirs_scanned;
/** The number of non-directories scanned so far, not counting
* excluded/unsupported files. */
uint64_t num_nondirs_scanned;
/** The number of bytes of file data detected so far, not
* counting excluded/unsupported files. */
uint64_t num_bytes_scanned;
} scan;
/** Valid on messages
* ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN,
* ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN,
* ::WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN,
* ::WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE,
* ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS,
* ::WIMLIB_PROGRESS_MSG_EXTRACT_METADATA,
* ::WIMLIB_PROGRESS_MSG_EXTRACT_TREE_END, and
* ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END.
*
* Note: most of the time of an extraction operation will be spent
* extracting file data, and the application will receive
* ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS during this time. Using @p
* completed_bytes and @p total_bytes, the application can calculate a
* percentage complete. However, there is no way for applications to
* know which file is currently being extracted. This is by design
* because the best way to complete the extraction operation is not
* necessarily file-by-file.
*/
struct wimlib_progress_info_extract {
/** The 1-based index of the image from which files are being
* extracted. */
uint32_t image;
/** Extraction flags being used. */
uint32_t extract_flags;
/** If the ::WIMStruct from which the extraction being performed
* has a backing file, then this is an absolute path to that
* backing file. Otherwise, this is @c NULL. */
const wimlib_tchar *wimfile_name;
/** Name of the image from which files are being extracted, or
* the empty string if the image is unnamed. */
const wimlib_tchar *image_name;
/** Path to the directory or NTFS volume to which the files are
* being extracted. */
const wimlib_tchar *target;
/** Reserved. */
const wimlib_tchar *reserved;
/** The number of bytes of file data that will be extracted. */
uint64_t total_bytes;
/** The number of bytes of file data that have been extracted so
* far. This starts at 0 and ends at @p total_bytes. */
uint64_t completed_bytes;
/** The number of file streams that will be extracted. This
* will often be similar to the "number of files", but for
* several reasons (hard links, named data streams, empty files,
* etc.) it can be different. */
uint64_t total_streams;
/** The number of file streams that have been extracted so far.
* This starts at 0 and ends at @p total_streams. */
uint64_t completed_streams;
/** Currently only used for
* ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN. */
uint32_t part_number;
/** Currently only used for
* ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN. */
uint32_t total_parts;
/** Currently only used for
* ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN. */
uint8_t guid[WIMLIB_GUID_LEN];
/** For ::WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE and
* ::WIMLIB_PROGRESS_MSG_EXTRACT_METADATA messages, this is the
* number of files that have been processed so far. Once the
* corresponding phase of extraction is complete, this value
* will be equal to @c end_file_count. */
uint64_t current_file_count;
/** For ::WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE and
* ::WIMLIB_PROGRESS_MSG_EXTRACT_METADATA messages, this is
* total number of files that will be processed.
*
* This number is provided for informational purposes only, e.g.
* for a progress bar. This number will not necessarily be
* equal to the number of files actually being extracted. This
* is because extraction backends are free to implement an
* extraction algorithm that might be more efficient than
* processing every file in the "extract file structure" and
* "extract file metadata" phases. For example, the current
* implementation of the UNIX extraction backend will create
* files on-demand during the "extract file data" phase.
* Therefore, when using that particular extraction backend, @p
* end_file_count will only include directories and empty files.
*/
uint64_t end_file_count;
} extract;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_RENAME. */
struct wimlib_progress_info_rename {
/** Name of the temporary file that the WIM was written to. */
const wimlib_tchar *from;
/** Name of the original WIM file to which the temporary file is
* being renamed. */
const wimlib_tchar *to;
} rename;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND and
* ::WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND. */
struct wimlib_progress_info_update {
/** Pointer to the update command that will be executed or has
* just been executed. */
const struct wimlib_update_command *command;
/** Number of update commands that have been completed so far.
*/
size_t completed_commands;
/** Number of update commands that are being executed as part of
* this call to wimlib_update_image(). */
size_t total_commands;
} update;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY and
* ::WIMLIB_PROGRESS_MSG_CALC_INTEGRITY. */
struct wimlib_progress_info_integrity {
/** The number of bytes in the WIM file that are covered by
* integrity checks. */
uint64_t total_bytes;
/** The number of bytes that have been checksummed so far. This
* starts at 0 and ends at @p total_bytes. */
uint64_t completed_bytes;
/** The number of individually checksummed "chunks" the
* integrity-checked region is divided into. */
uint32_t total_chunks;
/** The number of chunks that have been checksummed so far.
* This starts at 0 and ends at @p total_chunks. */
uint32_t completed_chunks;
/** The size of each individually checksummed "chunk" in the
* integrity-checked region. */
uint32_t chunk_size;
/** For ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY messages, this is
* the path to the WIM file being checked. */
const wimlib_tchar *filename;
} integrity;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART and
* ::WIMLIB_PROGRESS_MSG_SPLIT_END_PART. */
struct wimlib_progress_info_split {
/** Total size of the original WIM's file and metadata resources
* (compressed). */
uint64_t total_bytes;
/** Number of bytes of file and metadata resources that have
* been copied out of the original WIM so far. Will be 0
* initially, and equal to @p total_bytes at the end. */
uint64_t completed_bytes;
/** Number of the split WIM part that is about to be started
* (::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART) or has just been
* finished (::WIMLIB_PROGRESS_MSG_SPLIT_END_PART). */
unsigned cur_part_number;
/** Total number of split WIM parts that are being written. */
unsigned total_parts;
/** Name of the split WIM part that is about to be started
* (::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART) or has just been
* finished (::WIMLIB_PROGRESS_MSG_SPLIT_END_PART). Since
* wimlib v1.7.0, the library user may change this when
* receiving ::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART in order to
* cause the next split WIM part to be written to a different
* location. */
wimlib_tchar *part_name;
} split;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_REPLACE_FILE_IN_WIM */
struct wimlib_progress_info_replace {
/** Path to the file in the image that is being replaced */
const wimlib_tchar *path_in_wim;
} replace;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_WIMBOOT_EXCLUDE */
struct wimlib_progress_info_wimboot_exclude {
/** Path to the file in the image */
const wimlib_tchar *path_in_wim;
/** Path to which the file is being extracted */
const wimlib_tchar *extraction_path;
} wimboot_exclude;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_UNMOUNT_BEGIN. */
struct wimlib_progress_info_unmount {
/** Path to directory being unmounted */
const wimlib_tchar *mountpoint;
/** Path to WIM file being unmounted */
const wimlib_tchar *mounted_wim;
/** 1-based index of image being unmounted. */
uint32_t mounted_image;
/** Flags that were passed to wimlib_mount_image() when the
* mountpoint was set up. */
uint32_t mount_flags;
/** Flags passed to wimlib_unmount_image(). */
uint32_t unmount_flags;
} unmount;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_DONE_WITH_FILE. */
struct wimlib_progress_info_done_with_file {
/**
* Path to the file whose data has been written to the WIM file,
* or is currently being asynchronously compressed in memory,
* and therefore is no longer needed by wimlib.
*
* WARNING: The file data will not actually be accessible in the
* WIM file until the WIM file has been completely written.
* Ordinarily you should <b>not</b> treat this message as a
* green light to go ahead and delete the specified file, since
* that would result in data loss if the WIM file cannot be
* successfully created for any reason.
*
* If a file has multiple names (hard links),
* ::WIMLIB_PROGRESS_MSG_DONE_WITH_FILE will only be received
* for one name. Also, this message will not be received for
* empty files or reparse points (or symbolic links), unless
* they have nonempty named data streams.
*/
const wimlib_tchar *path_to_file;
} done_with_file;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_BEGIN_VERIFY_IMAGE and
* ::WIMLIB_PROGRESS_MSG_END_VERIFY_IMAGE. */
struct wimlib_progress_info_verify_image {
const wimlib_tchar *wimfile;
uint32_t total_images;
uint32_t current_image;
} verify_image;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_VERIFY_STREAMS. */
struct wimlib_progress_info_verify_streams {
const wimlib_tchar *wimfile;
uint64_t total_streams;
uint64_t total_bytes;
uint64_t completed_streams;
uint64_t completed_bytes;
} verify_streams;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_TEST_FILE_EXCLUSION. */
struct wimlib_progress_info_test_file_exclusion {
/**
* Path to the file for which exclusion is being tested.
*
* UNIX capture mode: The path will be a standard relative or
* absolute UNIX filesystem path.
*
* NTFS-3G capture mode: The path will be given relative to the
* root of the NTFS volume, with a leading slash.
*
* Windows capture mode: The path will be a Win32 namespace
* path to the file.
*/
const wimlib_tchar *path;
/**
* Indicates whether the file or directory will be excluded from
* capture or not. This will be <c>false</c> by default. The
* progress function can set this to <c>true</c> if it decides
* that the file needs to be excluded.
*/
bool will_exclude;
} test_file_exclusion;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_HANDLE_ERROR. */
struct wimlib_progress_info_handle_error {
/** Path to the file for which the error occurred, or NULL if
* not relevant. */
const wimlib_tchar *path;
/** The wimlib error code associated with the error. */
int error_code;
/**
* Indicates whether the error will be ignored or not. This
* will be <c>false</c> by default; the progress function may
* set it to <c>true</c>.
*/
bool will_ignore;
} handle_error;
};Решение задачи: «C++ Union в C#»
textual
Листинг программы
[StructLayout(LayoutKind.Explicit)]
struct wimlib_progress_info
{
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_write_streams
{
public ulong total_bytes;
public ulong total_streams;
public ulong completed_bytes;
public ulong completed_streams;
public uint num_threads;
public int compression_type;
public uint total_parts;
public uint completed_parts;
}
[StructLayout(LayoutKind.Explicit)]
public struct wimlib_progress_info_scan
{
[FieldOffset(0)]
public IntPtr source;
[FieldOffset(4)]
public IntPtr cur_path;
[FieldOffset(8)]
public int status; // enum
[FieldOffset(12)]
public IntPtr wim_target_path;
[FieldOffset(12)]
public IntPtr symlink_target;
[FieldOffset(16)]
public ulong num_dirs_scanned;
[FieldOffset(24)]
public ulong num_nondirs_scanned;
[FieldOffset(32)]
public ulong num_bytes_scanned;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_extract
{
public uint image;
public uint extract_flags;
public IntPtr wimfile_name;
public IntPtr image_name;
public IntPtr target;
public IntPtr reserved;
public ulong total_bytes;
public ulong completed_bytes;
public ulong total_streams;
public ulong completed_streams;
public uint part_number;
public uint total_parts;
unsafe fixed byte guid[16];
public ulong current_file_count;
public ulong end_file_count;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_rename
{
public IntPtr from;
public IntPtr to;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_update
{
public IntPtr command; // pointer to struct wimlib_update_command
public uint completed_commands;
public uint total_commands;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_integrity
{
public ulong total_bytes;
public ulong completed_bytes;
public uint total_chunks;
public uint completed_chunks;
public uint chunk_size;
public IntPtr filename;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_split
{
public ulong total_bytes;
public ulong completed_bytes;
public uint cur_part_number;
public uint total_parts;
public IntPtr part_name;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_replace
{
public IntPtr path_in_wim;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_wimboot_exclude
{
public IntPtr path_in_wim;
public IntPtr extraction_path;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_unmount
{
public IntPtr mountpoint;
public IntPtr mounted_wim;
public uint mounted_image;
public uint mount_flags;
public uint unmount_flags;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_done_with_file
{
public IntPtr path_to_file;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_verify_image
{
public IntPtr wimfile;
public uint total_images;
public uint current_image;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_verify_streams
{
public IntPtr wimfile;
public ulong total_streams;
public ulong total_bytes;
public ulong completed_streams;
public ulong completed_bytes;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_test_file_exclusion
{
public IntPtr path;
public bool will_exclude;
}
[StructLayout(LayoutKind.Sequential)]
public struct wimlib_progress_info_handle_error
{
public IntPtr path;
public int error_code;
public bool will_ignore;
}
[FieldOffset(0)]
public wimlib_progress_info_write_streams write_streams;
[FieldOffset(0)]
public wimlib_progress_info_scan scan;
[FieldOffset(0)]
public wimlib_progress_info_extract extract;
[FieldOffset(0)]
public wimlib_progress_info_rename rename;
[FieldOffset(0)]
public wimlib_progress_info_update update;
[FieldOffset(0)]
public wimlib_progress_info_integrity integrity;
[FieldOffset(0)]
public wimlib_progress_info_split split;
[FieldOffset(0)]
public wimlib_progress_info_replace replace;
[FieldOffset(0)]
public wimlib_progress_info_wimboot_exclude wimboot_exclude;
[FieldOffset(0)]
public wimlib_progress_info_unmount unmount;
[FieldOffset(0)]
public wimlib_progress_info_done_with_file done_with_file;
[FieldOffset(0)]
public wimlib_progress_info_verify_image verify_image;
[FieldOffset(0)]
public wimlib_progress_info_verify_streams verify_streams;
[FieldOffset(0)]
public wimlib_progress_info_test_file_exclusion test_file_exclusion;
[FieldOffset(0)]
public wimlib_progress_info_handle_error handle_error;
}