从C#调用Rand或SRand(在Windows 7 x64中) [英] PInvoke Rand or SRand from C# (in Windows 7 x64)

查看:130
本文介绍了从C#调用Rand或SRand(在Windows 7 x64中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法正确P调用C Rand和SRand函数.
我在x64和x86模式下都尝试过,但是堆栈不平衡或只有两位数字(38 41 45 ...).
我相信我们应该期望更大的数字0lt; = n< 2 ^ 32.

任何人都可以发现问题:

X64

I can''t manage to PInvoke properly the C Rand and SRand functions.
I tried in both x64 and x86 modes but I get either unbalanced stacks or just two digits numbers (38 41 45...).
I believe we should be expecting much bigger numbers 0<=n<2^32.

Can anyone spot the problem:

X64

//[DllImport(@"C:\Windows\SysWOW64\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
[DllImport(@"C:\Windows\System32\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int64 srand(UInt64 seed);

//[DllImport(@"C:\Windows\SysWOW64\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
[DllImport(@"C:\Windows\System32\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int64 rand();


public static void Main()
{
    for (uint i = 0; i < 10; i++)
    {
        srand(i);
        Console.WriteLine(rand());
    }

}




X86




X86

[DllImport(@"C:\Windows\SysWOW64\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
//[DllImport(@"C:\Windows\System32\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int64 srand(UInt32 seed);

[DllImport(@"C:\Windows\SysWOW64\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
//[DllImport(@"C:\Windows\System32\msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 rand();


public static void Main()
{
    for (uint i = 0; i < 10; i++)
    {
        srand(i);
        Console.WriteLine(rand());
    }

}

推荐答案

是的,我现在可以看到一些问题.

路径"C:\ Windows \ System32 \ msvcrt.dll"不可移植. System32实际上可以安装在任何目录中.由于这是Windows API,因此通常的适当且有效的技术是使用不带完整路径的文件名.在32位系统上应以32位版本解析,而在64位系统上应以64位版本解析.但是,这不是您的问题的根源.我希望您也知道,您不能在同一过程中混合使用不同的指令集目标体系结构.该程序集可能会编译,但这会导致运行时崩溃.

由于这是Windows API,因此需要使用System.Runtime.InteropServices.StdCall.这是Windows OS调用的默认约定,因此您可以简单地忽略此参数.请参阅 http://msdn.microsoft.com/en-us/library/system .runtime.interopservices.callingconvention.aspx [ ^ ].您最有可能观察到的问题是由于错误的调用约定引起的.

为什么不使用.NET类System.Random http://msdn.microsoft.com/en-us/library/system.random.aspx [ ^ ]?好吧,有人说这个生成器的统计质量并不完美,但是什么告诉您msvcrt.dll rand更好呢?

例如,看一下下面的CodeProject文章:
简单随机数生成 [随机数生成中的陷阱 [
Yes, I can see a couple of problems right now.

The path "C:\Windows\System32\msvcrt.dll" is not portable. System32 can actually be installed in any directory. As this is Windows API, the usual appropriate and valid technique is using a file name without full path. It should be resolved in 32-bit version on 32-bit system and 64-bit version on 64-bit system. However, this is not a source of your problem. I hope you also know that you cannot mix different instruction-set target architectures in the same process. The assembly may compile, but this would lead to a crash during run time.

As this is Windows API, you need to use System.Runtime.InteropServices.StdCall. This the default convention for Windows OS calls, so you can simply omit this parameter. See http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx[^]. Most likely, the problem you observe is due to wrong calling conventions.

Why not staying with platform-portable solution by using the .NET class System.Random, http://msdn.microsoft.com/en-us/library/system.random.aspx[^]? Well, some say that statistical quality of this generator is not perfect, but what tells you that msvcrt.dll rand is any better?

For example, take a look at this CodeProject articles:
Simple Random Number Generation[^],
Pitfalls in Random Number Generation[^].


—SA


这篇关于从C#调用Rand或SRand(在Windows 7 x64中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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