从C#调用Rand或SRand(在Windows 7 x64中) [英] PInvoke Rand or SRand from C# (in Windows 7 x64)
本文介绍了从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.dllrand
更好呢?
例如,看一下下面的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 useSystem.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 classSystem.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.dllrand
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屋!
查看全文