在c#中使用pinvoke在64位上调用sprintf和朋友 [英] Using pinvoke in c# to call sprintf and friends on 64-bit

查看:20
本文介绍了在c#中使用pinvoke在64位上调用sprintf和朋友的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C# 中使用 pinvoke 调用 _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.

我的代码如下,请记住,这是一个人为的示例,用于展示我所看到的行为.

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.

以下代码按预期工作:

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();
    }
}

这篇关于在c#中使用pinvoke在64位上调用sprintf和朋友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆