我有一个有趣的问题,使用的PInvoke在C#中调用_snwprintf。它的工作原理为整数类型,但不为浮点数。
I am having an interesting problem with using pinvoke in C# to call _snwprintf. It works for integer types, but not for floating point numbers.
这是在64位的Windows,它工作正常在32位。
This is on 64-bit Windows, it works fine on 32-bit.
我的code是下面,请记住,这是一个人为的例子来说明,我看到的行为。
My code is below, please keep in mind that this is a contrived example to show the behavior I am seeing.
class Program
{
[DllImport("msvcrt.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern int _snwprintf([MarshalAs(UnmanagedType.LPWStr)] StringBuilder str, IntPtr length, String format, int p);
[DllImport("msvcrt.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern int _snwprintf([MarshalAs(UnmanagedType.LPWStr)] StringBuilder str, IntPtr length, String format, double p);
static void Main(string[] args)
{
Double d = 1.0f;
Int32 i = 1;
Object o = (object)d;
StringBuilder str = new StringBuilder(32);
_snwprintf(str, (IntPtr)str.Capacity, "%10.1lf", (Double)o);
Console.WriteLine(str.ToString());
o = (object)i;
_snwprintf(str, (IntPtr)str.Capacity, "%10d", (Int32)o);
Console.WriteLine(str.ToString());
Console.ReadKey();
}
}
该程序的输出为
0.0
1
这应该打印1.0的第一线,而不是0.0,到目前为止,我难住了。
It should print 1.0 on the first line and not 0.0, and so far I am stumped.
我不完全相信你的话费为何不工作,但是的这些方法的安全版本不要在x86和x64的正常工作。
I'm not exactly sure why your calls do not work, but the secured versions of these methods do work properly in both x86 and x64.
下面code没有工作,符合市场预期:
The following code does work, as expected:
class Program
{
[DllImport("msvcrt.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern int _snwprintf_s([MarshalAs(UnmanagedType.LPWStr)] StringBuilder str, IntPtr bufferSize, IntPtr length, String format, int p);
[DllImport("msvcrt.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern int _snwprintf_s([MarshalAs(UnmanagedType.LPWStr)] StringBuilder str, IntPtr bufferSize, IntPtr length, String format, double p);
static void Main(string[] args)
{
// Preallocate this to a given length
StringBuilder str = new StringBuilder(100);
double d = 1.4;
int i = 7;
float s = 1.1f;
// No need for box/unbox
_snwprintf_s(str, (IntPtr)100, (IntPtr)32, "%10.1lf", d);
Console.WriteLine(str.ToString());
_snwprintf_s(str, (IntPtr)100, (IntPtr)32, "%10.1f", s);
Console.WriteLine(str.ToString());
_snwprintf_s(str, (IntPtr)100, (IntPtr)32, "%10d", i);
Console.WriteLine(str.ToString());
Console.ReadKey();
}
}