TTBase http://ttbase.sourceforge.jp/
逆P/Invoke http://www.artonx.org/diary/20081124.html#p01
これでC#でTTBaseのプラグイン作れるんじゃね?と思った。
TTBase.cs TTBaseで使用する構造体とか定数とか
using System; using System.Runtime.InteropServices; namespace TTBasePlugInTest { //プラグインのロードタイプ public enum LoadType { ptAlwayLoad = 0, ptLoadAtUse = 1, ptSpecViolation = 0xFFFF } //メニューに関する定数 public enum Menu { dmNone = 0, dmSystemMenu = 1, dmToolMenu = 2, dmHotKeyMenu = 4, dmMenuChecked = 8 } public enum LogOut { elNever = 0, elError = 1, elWarning = 2, elInfo = 3, elDebug = 4 } [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi)] public struct PLUGIN_COMMAND_INFO { [MarshalAs(UnmanagedType.LPStr)] public string Name; [MarshalAs(UnmanagedType.LPStr)] public string Caption; public int CommandID; public int Attr; public int ResID; public int DispMenu; public uint TimerInterval; public uint TimerCounter; } [StructLayout(LayoutKind.Sequential,CharSet= CharSet.Ansi)] public struct PLUGIN_INFO { public ushort NeedVersion; [MarshalAs(UnmanagedType.LPStr)] public string Name; [MarshalAs(UnmanagedType.LPStr)] public string FileName; public ushort PluginType; public uint VersionMS; public uint VersionLS; public uint CommandCount; [MarshalAs(UnmanagedType.LPStruct)] public IntPtr Commands; //public PLUGIN_COMMAND_INFO Commands; public uint LoadTime; } }
Class1.cs TTBaseに公開するメソッドを実装
using System; using System.Runtime.InteropServices; namespace TTBasePlugInTest { public class Class1 { public static IntPtr TTBEVent_InitPluginInfo(string PluginFilename) { PLUGIN_INFO r = new PLUGIN_INFO(); r.FileName = PluginFilename; r.NeedVersion = 0; r.Name = "テスト"; r.PluginType = (int)LoadType.ptAlwayLoad; r.CommandCount = 1; PLUGIN_COMMAND_INFO pci = new PLUGIN_COMMAND_INFO(); pci.Name = "test"; pci.Caption = "てすてす、テストのテストです"; pci.CommandID = 0; pci.DispMenu = (int)(Menu.dmToolMenu | Menu.dmHotKeyMenu); IntPtr pciPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pci)); Marshal.StructureToPtr(pci, pciPtr, false); r.Commands = pciPtr; //r.Commands = pci; IntPtr iPtr = Marshal.AllocHGlobal(Marshal.SizeOf(r)); Marshal.StructureToPtr(r, iPtr, false); return iPtr; } public static void TTBEvent_FreePluginInfo(IntPtr PluginInfo) { Marshal.FreeHGlobal(PluginInfo); } public static int TTBEvent_Init(string PluginFilename, int hPlugin) { return 1; } public static void TTBEvent_Unload() { } static int i; public static int TTBEvent_Execute(int CommandID, IntPtr hWnd) { i++; System.Windows.Forms.MessageBox.Show(i.ToString()); return 1; } public static void TTBEvent_WindowsHook(int Msg, int wParam, int lParam) { } } }
上のコードをビルドしたら
D:\My Documents\Visual Studio 2008\Projects\TTBasePlugInTest\TTBasePlugInTest\bi
n\Release>ildasm /OUT=TTBasePlugInTest.il TTBasePlugInTest.dll
でILにする。
逆P/Invokeを参考にILを編集
D:\My Documents\Visual Studio 2008\Projects\TTBasePlugInTest\TTBasePlugInTest\bi
n\Release>c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ilasm.exe /DLL TTBasePlu
gInTest.il
Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.3053
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'TTBasePlugInTest.il' to DLL --> 'TTBasePlugInTest.dll'
Source file is ANSI
Assembled method TTBasePlugInTest.Class1::TTBEVent_InitPluginInfo
Assembled method TTBasePlugInTest.Class1::TTBEvent_FreePluginInfo
Assembled method TTBasePlugInTest.Class1::TTBEvent_Init
Assembled method TTBasePlugInTest.Class1::TTBEvent_Unload
Assembled method TTBasePlugInTest.Class1::TTBEvent_Execute
Assembled method TTBasePlugInTest.Class1::TTBEvent_WindowsHook
Assembled method TTBasePlugInTest.Class1::.ctor
Creating PE file
Emitting classes:
Class 1: TTBasePlugInTest.Class1
Class 2: TTBasePlugInTest.PLUGIN_INFO
Class 3: TTBasePlugInTest.PLUGIN_COMMAND_INFO
Class 4: TTBasePlugInTest.LoadType
Class 5: TTBasePlugInTest.Menu
Class 6: TTBasePlugInTest.LogOut
Emitting fields and methods:
Global
Class 1 Fields: 1; Methods: 7;
Class 2 Fields: 9;
Class 3 Fields: 8;
Class 4 Fields: 4;
Class 5 Fields: 6;
Class 6 Fields: 6;
Resolving local member refs: 13 -> 13 defs, 0 refs, 0 unresolved
Emitting events and properties:
Global
Class 1
Class 2
Class 3
Class 4
Class 5
Class 6
Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Operation completed successfully
とILからDLLを作成。メッセージの意味はよくわからないけど、多分成功してる。
これで出来たDLLをTTBaseのディレクトリにコピーしてTTBaseを起動するも…プラグインとして認識されない。
どこが上手く行ってないのかもわからない状態。
http://twitter.com/takeshik/statuses/2419234928
とか言われたけどC++/CLIとかキモいし。
http://twitter.com/takeshik/statuses/2419254967
とか突っ込まれたけどその通りだと思う。
C#でやることに意味があるのですよ。C#可愛いよ、C#可愛い。
でもC#で出来て無いから何の意味も無いという…。