It does, indeed, look like a compiler bug. I tested this with Mono 2.10.8. Small modification of your program, just playing around with different calls, it doesn’t actually seem to matter all that much. The program either fails on the delegate call or on the method return.
// dlltest.cs
using System.Runtime;
using System.Runtime.InteropServices;
using System.Text;
public class DllTest
{
[DllImport("msvcrt", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int sprintf(StringBuilder buffer, string format, __arglist);
static public void Main()
{
StringBuilder str = new StringBuilder();
DllTest.sprintf(str, "Hello %s", __arglist("World"));
}
}
e:\Program Files (x86)\Mono-2.10.8\bin>gmcs dlltest.cs
e:\Program Files (x86)\Mono-2.10.8\bin>mono dlltest.exe
Unhandled Exception: System.InvalidProgramException: Invalid IL code in DllTest:Main (): IL_0017: ret
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidProgramException: Invalid IL code in DllTest:Main (): IL_0017: ret
Here’s the disassembled exe…
e:\Program Files (x86)\Mono-2.10.8\bin>monodis dlltest.exe --output=dlltestIL.txt
e:\Program Files (x86)\Mono-2.10.8\bin>view dlltestIL.txt
‘view’ is not recognized as an internal or external command,
operable program or batch file.
e:\Program Files (x86)\Mono-2.10.8\bin>more dlltestIL.txt
.assembly extern mscorlib
{
.ver 2:0:0:0
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
}
.assembly 'dlltest'
{
.custom instance void class [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::'.ctor'() = (
01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module dlltest.exe // GUID = {80996749-6E58-498A-A2DA-7372ADD10FE0}
.module extern 'msvcrt'
.class public auto ansi beforefieldinit DllTest
extends [mscorlib]System.Object
{
// method line 1
.method public hidebysig specialname rtspecialname
instance default void '.ctor' () cil managed
{
// Method begins at RVA 0x20ec
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void object::'.ctor'()
IL_0006: ret
} // end of method DllTest::.ctor
// method line 2
.method private static hidebysig pinvokeimpl ("msvcrt" as "sprintf" ansi cdecl )
vararg int32 sprintf (class [mscorlib]System.Text.StringBuilder buffer, string format) cil managed preservesig
{
// Method begins at RVA 0x0
} // end of method DllTest::sprintf
// method line 3
.method public static hidebysig
default void Main () cil managed
{
// Method begins at RVA 0x20f4
.entrypoint
// Code size 24 (0x18)
.maxstack 4
.locals init (
class [mscorlib]System.Text.StringBuilder V_0)
IL_0000: newobj instance void class [mscorlib]System.Text.StringBuilder::'.ctor'()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: ldstr "Hello %s"
IL_000c: ldstr "World"
IL_0011: call vararg int32 class DllTest::sprintf(class [mscorlib]System.Text.StringBuilder, string, ..., string)
IL_0016: pop
IL_0017: ret <----------- Invalid Instruction???
} // end of method DllTest::Main
} // end of class DllTest
I’ll go ahead and toss this up on Mono’s bug tracker.