C#/.NET 泛型和 Cdecl Varargs 错误?
为什么 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)); }
}
Why does Foo()
succeed but Bar()
throws a 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)); }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试这样:
Try like this:
您问为什么未记录的(_arglist、_makeref、_reftype、_refvalue)关键字不起作用。
好吧,你应该问 Microsoft:D
如果你真的想知道我对此的看法,可能是因为泛型在编译时不知道 T 的类型,但它们被编译为类。 __arglist 在编译时采用什么是一个谜。因为在声明泛型的行中没有指定 __arglist 的参数类型。
但所有这些都像在 C# 中使用 sprintf 一样晦涩难懂...至少如果它是 _snwprintf_s 或类似的:D
You are asking why an undocumented (_arglist,_makeref,_reftype,_refvalue) keyword does not work.
Well you should ask Microsoft :D
If you really want to know my take on this, it could be because generics don't know the type of T at compile time, and yet they are compiled to classes. What does __arglist take at compilation time there is a mystery. Since in the line where you declare the generic don't specify the kind of parameter to __arglist.
But all of this is as much obscure as using sprintf from C#... at least if it were _snwprintf_s or similar :D
如下面的代码所示,当该方法被编译为本机代码时,在运行该方法之前会抛出异常:
此外,它还抱怨传递给 SizeOf 的类型错误。我猜想这可能是 CLR 中的一个错误,导致它将内部句柄传递给泛型类型参数,而不是传递给方法的真实类型的句柄。
As shown in the following code, the exception is thrown before running the method when it is compiled into native code:
Also it is complaining about wrong type passed to SizeOf. I guess it might be a bug in the CLR that causes it to pass the internal handle to the generic type parameter instead of the handle of the real type passed to the method.