D
dadi.armannss
Hi
I have been experimenting with writing managed libraries (C#/.NET 2.0)
for use in native applications with good results. This has been
achieved by disassembling the managed library, adding IL code to
export the required functions, and then using ILAsm to re-assemble
the .NET assembly. The IL code changes required are the following:
..corflags 0x00000001 -> .corflags 0x00000002
Added:
..vtfixup [1] int32 fromunmanaged at VT_01
..data VT_01 = int32(0)
Added within exported function scope:
..vtentry 1 : 1
..export [1] as Test
After applying these changes, one can use the managed library as if it
was native, either from a native app, using LoadLibrary/
GetProcAddress, or from a managed app using DllImport.
Now when I do the same for a compact framework assembly and try to
load and execute a function from that managed library on Windows CE
5.0, I get an access violation.
I have confirmed that the code that loads the library is successful in
locating the exported lib function, so the access violation is either
in the lib function or somewhere in the glue between the native app
and the managed lib. The code for each follows:
[Native application]
typedef void (*PFN_Test)(void);
void main() {
HINSTANCE hManagedLib = LoadLibrary(_T("CFManagedDLL.dll"));
if( hManagedLib ) {
PFN_Test exportedFunc =
(PFN_Test)GetProcAddress(hManagedLib, L"Test");
if( exportedFunc != NULL)
exportedFunc();
}
return 0;
}
[Managed library]
using System;
using System.Collections.Generic;
using System.Text;
namespace CFManagedDLL {
public class Class1 {
public static void Test() {
System.Console.Out.WriteLine("Compact Framework Managed
DLL");
}
}
}
[Altered IL Code for Managed library]
..assembly extern mscorlib
{
.publickeytoken = (96 9D B8 05 3D 33 22
AC ) // ....=3".
.ver 2:0:0:0
}
..assembly CFManagedDLL
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string)
= ( 01 00 24 31 36 34 31 61 66 34 38 2D 65 37 63 62 // ..$1641af48-
e7cb
2D 34 61 64 31 2D 38 36 63 32 2D 66 62 37 32 36 // -4ad1-86c2-fb726
34 39 34 62 66 65 30 00 00 ) // 494bfe0..
.custom instance void
[mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string)
= ( 01 00 12 43 6F 70 79 72 69 67 68 74 20 C2 A9
20 // ...Copyright ..
20 32 30 30 37 00 00 ) // 2007..
.custom instance void
[mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) =
( 01 00 0C 43 46 4D 61 6E 61 67 65 64 44 4C 4C
00 // ...CFManagedDLL.
00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) =
( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) =
( 01 00 0C 43 46 4D 61 6E 61 67 65 64 44 4C 4C
00 // ...CFManagedDLL.
00 )
// --- The following custom attribute is added automatically, do not
uncomment -------
// .custom instance void
[mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype
[mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) =
( 01 00 07 01 00 00 00 00 )
.hash algorithm 0x00008004
.ver 1:0:2602:17354
}
..module CFManagedDLL.dll
// MVID: {C072D8C7-8D33-477C-BB9C-275822BD1E76}
..imagebase 0x00400000
..file alignment 0x00001000
..stackreserve 0x00100000
..subsystem 0x0009 // WINDOWS_CUI
..corflags 0x00000002
..vtfixup [1] int32 fromunmanaged at VT_01
..data VT_01 = int32(0)
// Image base: 0x005F0000
// =============== CLASS MEMBERS DECLARATION ===================
..class public auto ansi beforefieldinit CFManagedDLL.Class1
extends [mscorlib]System.Object
{
.method public hidebysig static void Test() cil managed
{
.vtentry 1 : 1
.export [1] as Test
// Code size 18 (0x12)
.maxstack 8
IL_0000: nop
IL_0001: call class [mscorlib]System.IO.TextWriter
[mscorlib]System.Console::get_Out()
IL_0006: ldstr "Compact Framework Managed DLL"
IL_000b: callvirt instance void
[mscorlib]System.IO.TextWriter::WriteLine(string)
IL_0010: nop
IL_0011: ret
} // end of method Class1::Test
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void
[mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Class1::.ctor
} // end of class CFManagedDLL.Class1
I have been experimenting with writing managed libraries (C#/.NET 2.0)
for use in native applications with good results. This has been
achieved by disassembling the managed library, adding IL code to
export the required functions, and then using ILAsm to re-assemble
the .NET assembly. The IL code changes required are the following:
..corflags 0x00000001 -> .corflags 0x00000002
Added:
..vtfixup [1] int32 fromunmanaged at VT_01
..data VT_01 = int32(0)
Added within exported function scope:
..vtentry 1 : 1
..export [1] as Test
After applying these changes, one can use the managed library as if it
was native, either from a native app, using LoadLibrary/
GetProcAddress, or from a managed app using DllImport.
Now when I do the same for a compact framework assembly and try to
load and execute a function from that managed library on Windows CE
5.0, I get an access violation.
I have confirmed that the code that loads the library is successful in
locating the exported lib function, so the access violation is either
in the lib function or somewhere in the glue between the native app
and the managed lib. The code for each follows:
[Native application]
typedef void (*PFN_Test)(void);
void main() {
HINSTANCE hManagedLib = LoadLibrary(_T("CFManagedDLL.dll"));
if( hManagedLib ) {
PFN_Test exportedFunc =
(PFN_Test)GetProcAddress(hManagedLib, L"Test");
if( exportedFunc != NULL)
exportedFunc();
}
return 0;
}
[Managed library]
using System;
using System.Collections.Generic;
using System.Text;
namespace CFManagedDLL {
public class Class1 {
public static void Test() {
System.Console.Out.WriteLine("Compact Framework Managed
DLL");
}
}
}
[Altered IL Code for Managed library]
..assembly extern mscorlib
{
.publickeytoken = (96 9D B8 05 3D 33 22
AC ) // ....=3".
.ver 2:0:0:0
}
..assembly CFManagedDLL
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string)
= ( 01 00 24 31 36 34 31 61 66 34 38 2D 65 37 63 62 // ..$1641af48-
e7cb
2D 34 61 64 31 2D 38 36 63 32 2D 66 62 37 32 36 // -4ad1-86c2-fb726
34 39 34 62 66 65 30 00 00 ) // 494bfe0..
.custom instance void
[mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string)
= ( 01 00 12 43 6F 70 79 72 69 67 68 74 20 C2 A9
20 // ...Copyright ..
20 32 30 30 37 00 00 ) // 2007..
.custom instance void
[mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) =
( 01 00 0C 43 46 4D 61 6E 61 67 65 64 44 4C 4C
00 // ...CFManagedDLL.
00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) =
( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string)
= ( 01 00 00 00 00 )
.custom instance void
[mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) =
( 01 00 0C 43 46 4D 61 6E 61 67 65 64 44 4C 4C
00 // ...CFManagedDLL.
00 )
// --- The following custom attribute is added automatically, do not
uncomment -------
// .custom instance void
[mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype
[mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) =
( 01 00 07 01 00 00 00 00 )
.hash algorithm 0x00008004
.ver 1:0:2602:17354
}
..module CFManagedDLL.dll
// MVID: {C072D8C7-8D33-477C-BB9C-275822BD1E76}
..imagebase 0x00400000
..file alignment 0x00001000
..stackreserve 0x00100000
..subsystem 0x0009 // WINDOWS_CUI
..corflags 0x00000002
..vtfixup [1] int32 fromunmanaged at VT_01
..data VT_01 = int32(0)
// Image base: 0x005F0000
// =============== CLASS MEMBERS DECLARATION ===================
..class public auto ansi beforefieldinit CFManagedDLL.Class1
extends [mscorlib]System.Object
{
.method public hidebysig static void Test() cil managed
{
.vtentry 1 : 1
.export [1] as Test
// Code size 18 (0x12)
.maxstack 8
IL_0000: nop
IL_0001: call class [mscorlib]System.IO.TextWriter
[mscorlib]System.Console::get_Out()
IL_0006: ldstr "Compact Framework Managed DLL"
IL_000b: callvirt instance void
[mscorlib]System.IO.TextWriter::WriteLine(string)
IL_0010: nop
IL_0011: ret
} // end of method Class1::Test
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void
[mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Class1::.ctor
} // end of class CFManagedDLL.Class1