| 著作一覧 |
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++に詳しくない人には便利かもと思っていたりします。