diff --git a/TTTConsole/Program.cs b/TTTConsole/Program.cs index 9e0f9b3..73567a3 100644 --- a/TTTConsole/Program.cs +++ b/TTTConsole/Program.cs @@ -10,28 +10,20 @@ class Program { - [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint ="IsHuman")] - private extern static bool IsHumanR(); + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr LoadLibrary(string lib); + [DllImport("kernel32.dll", SetLastError = true)] + public static extern void FreeLibrary(IntPtr module); + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr GetProcAddress(IntPtr module, string proc); - [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetName", CharSet = CharSet.Ansi)] - private extern static void GetNameR(StringBuilder s, Int32 bufsize); - - [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "MyTurn")] - private extern static int MyTurnR(IntPtr board); - - [DllImport("TPIRandom.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "IsHuman")] - private extern static bool IsHumanH(); - - [DllImport("TPIHuman.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetName", CharSet = CharSet.Ansi)] - private extern static void GetNameH(StringBuilder s, Int32 bufsize); - - [DllImport("TPIHuman.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "MyTurn")] - private extern static int MyTurnH(IntPtr board); - + private delegate void GetNameDelegate(StringBuilder s, Int32 bufsize); + private delegate bool IsHumanDelegate(); + private delegate int MyTurnDelegate(IntPtr board); static string[] PLAYER_STR = new string[] { "", "先手", "後手" }; static string[] PLAYER_MARK = new string[] { " ", "○", "×" }; - static string[] names; + static List names = new List(); static int[] thinkers; static bool showNumber = false; @@ -47,26 +39,74 @@ Console.WriteLine(""); var ttt = new TicTacToe(); + // プラグインDLLを開く + var pluginFiles = new List() { "TPIHuman.dll", "TPIRandom.dll" }; + var modules = new List(); + var GetName = new List(); + var IsHuman = new List(); + var MyTurn = new List(); + + foreach (var file in pluginFiles) { + var module = LoadLibrary(file); + if (module == IntPtr.Zero) // error handling + { + Console.WriteLine($"Could not load library: {Marshal.GetLastWin32Error()}"); + continue; + } + + IntPtr method = GetProcAddress(module, "GetName"); + if (method == IntPtr.Zero) // error handling + { + Console.WriteLine($"Could not load 'GetName' method: {Marshal.GetLastWin32Error()}"); + FreeLibrary(module); // unload library + continue; + } + GetName.Add((GetNameDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(GetNameDelegate))); + + method = GetProcAddress(module, "IsHuman"); + if (method == IntPtr.Zero) // error handling + { + Console.WriteLine($"Could not load 'IsHuman' method: {Marshal.GetLastWin32Error()}"); + FreeLibrary(module); // unload library + continue; + } + IsHuman.Add((IsHumanDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(IsHumanDelegate))); + + method = GetProcAddress(module, "MyTurn"); + if (method == IntPtr.Zero) // error handling + { + Console.WriteLine($"Could not load 'MyTurn' method: {Marshal.GetLastWin32Error()}"); + FreeLibrary(module); // unload library + continue; + } + MyTurn.Add((MyTurnDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(MyTurnDelegate))); + + modules.Add(module); + } + // プラグイン名の取得 System.Text.StringBuilder sb = new System.Text.StringBuilder(256); - names = new string[2]; - GetNameH(sb, sb.Capacity); - names[0] = sb.ToString(); - GetNameR(sb, sb.Capacity); - names[1] = sb.ToString(); + foreach (var gn in GetName) { + gn(sb, sb.Capacity); + names.Add(sb.ToString()); + } + //GetName[0](sb, sb.Capacity); + //names[0] = sb.ToString(); + //GetName[1](sb, sb.Capacity); + //names[1] = sb.ToString(); // プレイヤーの選択 Console.WriteLine("プレイヤーの選択"); thinkers = new int[ttt.PLAYERS]; for (var pl=0; pl< ttt.PLAYERS; pl++) { - for (var i = 0; i < names.Length; i++) { + for (var i = 0; i < names.Count; i++) { Console.WriteLine($"({i + 1}) {names[i]}"); } Console.Write($"{PLAYER_STR[pl + 1]} を選んでください: "); var input = Console.ReadLine(); if (!int.TryParse(input, out thinkers[pl])) return; - if (thinkers[pl] < 1 || thinkers[pl] > names.Length) return; + if (thinkers[pl] < 1 || thinkers[pl] > names.Count) return; --thinkers[pl]; } @@ -84,11 +124,11 @@ switch (thinkers[(int)ttt.Player - 1]) { case 0: Console.WriteLine(""); - ttt.Set(MyTurnH(ttt.GetBoard())); + //ttt.Set(MyTurnH(ttt.GetBoard())); break; case 1: - ttt.Set(MyTurnR(ttt.GetBoard())); - if (!IsHumanR()) Console.WriteLine($" --> {ttt.LastSet + 1}"); + //ttt.Set(MyTurnR(ttt.GetBoard())); + //if (!IsHumanR()) Console.WriteLine($" --> {ttt.LastSet + 1}"); break; } } while (ttt.Judge == JUDGE.None); @@ -117,6 +157,7 @@ // 終了 Console.Write("Press [Enter] to exit."); Console.ReadLine(); + foreach (var module in modules) FreeLibrary(module); } ///