著作一覧 |
MSKBの「DLLとは」というINFOは、シンプルな題名と裏腹になかなか楽しいことが書いてある。
が、いかんせん、中途半端で、しかもちょっと古いかも知れない。
試してみたが、clr2.5では、vtfixupについての修正は不要なようだ(メソッドシグネチャによるのかも知れないけど)。さらに.corflagsの修正も必要ない。
// MyAssembly.cs using System; public static class MyAsm { public static void HelloWorld() { Console.WriteLine("Hello World!"); } public static void HelloMyWorld(int count) { for (int i = 0; i < count; i++) Console.WriteLine("Hello My World!"); } }これを
c:\temp>csc /target:library MyAssembly.cs Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1 for Microsoft (R) .NET Framework version 3.5 Copyright (C) Microsoft Corporation. All rights reserved.でもって
c:\temp>ildasm /out:MyAssembly.il MyAssembly.dllさらに
c:\home\arton\temp>diff -u -2 MyAssembly.il~ MyAssembly.il --- MyAssembly.il~ Mon Nov 24 03:06:28 2008 +++ MyAssembly.il Mon Nov 24 03:07:27 2008 @@ -36,4 +36,5 @@ .method public hidebysig static void HelloWorld() cil managed { + .export [1] // コード サイズ 13 (0xd) .maxstack 8 @@ -47,4 +48,5 @@ .method public hidebysig static void HelloMyWorld(int32 count) cil managed { + .export [2] // コード サイズ 29 (0x1d) .maxstack 2としてから
c:\temp>ilasm /dll MyAssembly.il Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.3053 Copyright (c) Microsoft Corporation. All rights reserved. Assembling 'MyAssembly.il' to DLL --> 'MyAssembly.dll' Source file is ANSI Assembled method MyAsm::HelloWorld Assembled method MyAsm::HelloMyWorld Creating PE file Emitting classes: Class 1: MyAsm Emitting fields and methods: Global Class 1 Methods: 2; Emitting events and properties: Global Class 1 Writing PE file Operation completed successfullyで、dllができたので、一応corflagsを見てみる。
c:\temp>corflags MyAssembly.dll Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8 Copyright (c) Microsoft Corporation. All rights reserved. Version : v2.0.50727 CLR Header: 2.5 PE : PE32 CorFlags : 2 ILONLY : 0 32BIT : 1 Signed : 0というわけで、ILONLYは自動的に落とされていて問題なさそうなので、まずはCで逆P/Invoke(これがそうかはちょっと疑問)。
// impasm.c #include <windows.h> int main(int argc, char* argv[]) { HMODULE h = LoadLibrary("MyAssembly.dll"); FARPROC fnc = GetProcAddress(h, "HelloWorld"); fnc(); fnc = GetProcAddress(h, "HelloMyWorld"); ((void (*)(int))fnc)(2); return 0; }コンパイルして実行。
c:\temp>cl impasm.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. impasm.c Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:impasm.exe impasm.obj c:\temp>impasm Hello World! Hello My World! Hello My World!しかし、引数がintでstaticメンバ関数の呼び出しだからちょろいわけだが、オブジェクトを使いたかったり、文字列を使うには、やはり^とかが必要になると思うわけで、それほど嬉しくないかも。
ジェズイットを見習え |
いやー、有難うございます。<br>coflagsが落ちるのは、気がついて無かった。MSDNライブラリによれば、Managed C++のリンカでもできるらしいです(こっちは未確認)。<br>ラウンド・トリップ(C#-IL)は出来ないけど、C/C++に詳しくない人には便利かもと思っていたりします。