C#的互操作性:缓冲区、结构、指针
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace Interop { class Program { [DllImport("kernel32.dll", EntryPoint = "Beep")] public static extern bool MyBeep(uint iFreq, uint iDuration); //HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName); [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string dllName); delegate int deleMessageBox(IntPtr hWnd, string text, string caption, uint type); //GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。 //FARPROC GetProcAddress( // HMODULE hModule, // DLL模块句柄 // LPCSTR lpProcName // 函数名 // ); [DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); //CharSet = CharSet.Auto [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type); //DWORD GetCurrentDirectory(DWORD nBufferLength, //sizeofdirectorybuffer //LPTSTR lpBuffer //directorybuffer //); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern int GetCurrentDirectory(int BufferLength, System.Text.StringBuilder lpBuffer); //LPSTR GetCommandLine() [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern System.IntPtr GetCommandLine(); //结构体 //typedef struct{ // int wStructSize; // int x; // int y; // int dx; // int dy; // int wMax; // TCHAR rgchMember[2]; //}HELPWININFO; [StructLayout(LayoutKind.Sequential)] public struct HELPWININFO { int wStructSize; int x; int y; int dx; int dy; int wMax; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public char[] rgchMember; } static void Main(string[] args) { MyBeep(500, 500); //函数需要修改内存缓冲区,必须用StringBuilder,因为String类型是只读的 StringBuilder sb = new StringBuilder(255); GetCurrentDirectory(255, sb); Console.WriteLine(sb); //使用IntPtr类将返回的字符串保存到string中 IntPtr ptr = GetCommandLine(); string cmdline = Marshal.PtrToStringAuto(ptr); Console.WriteLine(cmdline); //GetProcAddress IntPtr ptrKernel32 = LoadLibrary("user32.dll"); IntPtr ptrProcMessageBox = GetProcAddress(ptrKernel32, "MessageBoxA"); deleMessageBox messageBox = Marshal.GetDelegateForFunctionPointer(ptrProcMessageBox, typeof(deleMessageBox)) as deleMessageBox; messageBox(IntPtr.Zero, @"public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);", "LoadLibrary", 0x40); MessageBox(IntPtr.Zero, "Content Here!", "Caption", 0x40); } } }