プラットフォーム呼び出しによるデータのマーシャリング
まだ完全には理解できていない部分があります。下記参照元を参考にして
とりあえず動くようにはなりましたが、構造体文字列メンバー値が正しく取得できない等
一部おかしなところがあります。
とりあえず動くようにはなりましたが、構造体文字列メンバー値が正しく取得できない等
一部おかしなところがあります。
サンプルソース
統合アーカイバプロジェクト の 7-ZIP32.DLL が提供している機能を使用するサンプル//使用する機能分だけマーシャリングしている。 //オリジナルの定義情報は、7-ZIP32.DLL付属のヘッダーファイルなどを参照すること。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace MarshalingSample { //#define FNAME_MAX32 512 //typedef struct { // DWORD dwFileSize; // DWORD dwWriteSize; // char szSourceFileName[FNAME_MAX32 + 1]; // char dummy1[3]; // char szDestFileName[FNAME_MAX32 + 1]; // char dummy[3]; //} EXTRACTINGINFO, *LPEXTRACTINGINFO; [StructLayout(LayoutKind.Sequential)] public struct EXTRACTINGINFO { public UInt32 dwFileSize; public UInt32 dwWriteSize; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.TBStr, SizeConst = 513)] public char[] szSourceFileName; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.TBStr, SizeConst = 3)] public char[] dummy1; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.TBStr, SizeConst = 513)] public char[] szDestFileName; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.TBStr, SizeConst = 3)] public char[] dummy; } //typedef struct { // EXTRACTINGINFO exinfo; // DWORD dwCompressedSize; // DWORD dwCRC; // UINT uOSType; // WORD wRatio; // WORD wDate; // WORD wTime; // char szAttribute[8]; // char szMode[8]; //} EXTRACTINGINFOEX, *LPEXTRACTINGINFOEX; [StructLayout(LayoutKind.Sequential)] public struct EXTRACTINGINFOEX { public EXTRACTINGINFO info; public UInt32 dwCompressedSize; public UInt32 dwCRC; public UInt16 uOSType; public UInt32 wRatio; public UInt32 wDate; public UInt32 wTime; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.TBStr, SizeConst = 8)] public char[] szAttribute; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.TBStr, SizeConst = 8)] public char[] szMode; } public class Zip { //typedef BOOL CALLBACK ARCHIVERPROC(HWND _hwnd, UINT _uMsg, UINT _nState, LPVOID _lpEis); public delegate bool ARCHIVERPROC(IntPtr _hwnd, UInt16 _uMsg, UInt16 _nState, IntPtr _ipEis); //int WINAPI SevenZip(const HWND _hwnd, LPCSTR _szCmdLine, LPSTR _szOutput, const DWORD _dwSize); [DllImport("7-zip32.dll", EntryPoint = "SevenZip")] public static extern int DeCompress(IntPtr _hwnd, string _szCmdLine, StringBuilder _szOutPut, UInt32 _dwSize); //BOOL WINAPI SevenZipSetOwnerWindowEx(HWND _hwnd, LPARCHIVERPROC _lpArcProc); [DllImport("7-zip32.dll", EntryPoint = "SevenZipSetOwnerWindowEx")] public static extern bool SetCallBack(IntPtr _hwnd, ARCHIVERPROC callback); } }
//7-ZIP32.DLL 機能を使用したサンプルアプリケーション //アプリケーションに*.zipファイルをドロップすると解凍を行うことができる //コールバック関数内で、解凍進捗をコンソールに出力している using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices; namespace MarshalingSample { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void MainForm_DragDrop(object sender, DragEventArgs e) { var dialog = new FolderBrowserDialog(); if (dialog.ShowDialog() != DialogResult.OK) return; var filename = ((String[])e.Data.GetData("FileDrop"))[0]; var cmd = "-hide e \"{zip}\" -o\"{out_path}\"".Replace("{zip}", filename); cmd = cmd.Replace("{out_path}", dialog.SelectedPath); var buffer = new StringBuilder(); Zip.SetCallBack(this.Handle, new Zip.ARCHIVERPROC(ProgressCallBack)); Zip.DeCompress(this.Handle, cmd, buffer, 0); } private bool ProgressCallBack(IntPtr _hwnd, UInt16 _uMsg, UInt16 _nState, IntPtr _ipEis) { EXTRACTINGINFOEX exinfo = (EXTRACTINGINFOEX)Marshal.PtrToStructure(_ipEis, typeof(EXTRACTINGINFOEX)); if (exinfo.info.dwFileSize > 0) Console.WriteLine("TotalSize:{0} CurrentSize:{1}", exinfo.info.dwFileSize, exinfo.info.dwWriteSize); return true; } private void MainForm_DragEnter(object sender, DragEventArgs e) { var filename = ((String[])e.Data.GetData("FileDrop"))[0]; if (Path.GetExtension(filename) == ".zip") e.Effect = DragDropEffects.Copy; else e.Effect = DragDropEffects.None; } } }