5

为什么Foo()成功但Bar()抛出一个BadImageFormatException

using System.Runtime.InteropServices;
using System.Text;

static class Program
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern int sprintf([Out] StringBuilder buf, string format, __arglist);

    static void Main(string[] args)
    {
        Foo<int>(2); //Runs fine
        Bar<int>(2); //Error: "The signature is incorrect"
    }

 static void Foo<T>(int a) { sprintf(new StringBuilder(8), "%d", __arglist(a)); }
 static void Bar<T>(T   a) { sprintf(new StringBuilder(8), "%d", __arglist(a)); }
}
4

3 回答 3

0

试试这样:

using System;
using System.Runtime.InteropServices;
using System.Text;

static class Program
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern int sprintf([Out] StringBuilder buf, string format, params object[] args);

    static void Main(string[] args)
    {
        Foo(2);
        Bar<int>(2);
    }

    static void Foo(int a) { sprintf(new StringBuilder(8), "%d", a); }
    static void Bar<T>(T a){ sprintf(new StringBuilder(8), "%d", a); }
}
于 2011-05-01T07:38:53.247 回答
0

您在问为什么未记录的 ( _arglist , _makeref,_ reftype, _refvalue) 关键字不起作用。

那么你应该问微软:D

如果您真的想知道我对此的看法,可能是因为泛型在编译时不知道 T 的类型,但它们被编译为类。__arglist 在编译时需要什么,这是一个谜。因为在您声明泛型的行中,请不要指定 __arglist 的参数类型。

但所有这一切都与使用 C# 中的 sprintf 一样晦涩难懂......至少如果它是 _snwprintf_s 或类似的:D

于 2011-05-01T07:49:48.640 回答
0

如下代码所示,编译成native代码时,方法在运行前抛出异常:

var t = typeof(Program);
var m = t.GetMethod("Bar", BindingFlags.NonPublic | BindingFlags.Static);
m = m.MakeGenericMethod(typeof(int));
System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(m.MethodHandle); //error

它还抱怨传递给SizeOf的错误类型。我猜这可能是 CLR 中的一个错误,导致它将内部句柄传递给泛型类型参数,而不是传递给方法的真实类型的句柄。

于 2014-07-21T12:27:20.360 回答