C# 如何通过编组从指针读取uint?

C# 如何通过编组从指针读取uint?,c#,pinvoke,marshalling,C#,Pinvoke,Marshalling,我有一个本机方法,它需要一个指针来写出dword(uint) 现在我需要从(Int)指针获取实际的uint值,但是Marshal类只有读取(有符号)整数的简便方法 如何从指针获取uint值 我已经搜索了这些问题(和谷歌),但找不到我真正需要的 示例(不工作)代码: 本机函数的返回值是一个介于0和255之间的dword,其中255是完全对比度。使用接受IntPtr和类型并传入typeof(uint)的-这应该可以工作 希望这有帮助 使用接受IntPtr和type并传入typeof(uint)的-这

我有一个本机方法,它需要一个指针来写出dword(uint)

现在我需要从(Int)指针获取实际的uint值,但是Marshal类只有读取(有符号)整数的简便方法

如何从指针获取uint值

我已经搜索了这些问题(和谷歌),但找不到我真正需要的

示例(不工作)代码:

本机函数的返回值是一个介于0和255之间的dword,其中255是完全对比度。

使用接受IntPtr和类型并传入typeof(uint)的-这应该可以工作

希望这有帮助

使用接受IntPtr和type并传入typeof(uint)的-这应该可以工作


希望这有帮助

您只需将其强制转换为
uint

uint contrast = (uint)Marshal.ReadInt32(pdwSetting);
例如:

int i = -1;
uint j = (uint)i;
Console.WriteLine(j);

输出
4294967295

您只需将其强制转换为
uint

uint contrast = (uint)Marshal.ReadInt32(pdwSetting);
例如:

int i = -1;
uint j = (uint)i;
Console.WriteLine(j);

输出
4294967295

取决于您是否可以使用usafe代码,您甚至可以执行以下操作:

static unsafe void Method()
{
    IntPtr pdwSetting = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint)));

    try
    {
        NativeMethods.JidaVgaGetContrast(_handleJida, pdwSetting);
        var contrast = *(uint*)pdwSetting;
    }
    finally
    {
        Marshal.FreeHGlobal(pdwSetting);
    }
}

注意,C++函数指针类似

void (*GetContrastPointer)(HANDLE handle, unsigned int* setting);
可以作为

[DllImport("*.dll")]
void GetContrast(IntPtr handle, IntPtr setting); // most probably what you did
但也作为

[DllImport("*.dll")]
void GetContrast(IntPtr handle, ref uint setting);
这样您就可以像这样编写代码

uint contrast = 0; // or some other invalid value
NativeMethods.JidaVgaGetContrast(_handleJida, ref contrast);

这在性能和可读性方面都非常出色。

根据您是否可以使用usafe代码,您甚至可以执行以下操作:

static unsafe void Method()
{
    IntPtr pdwSetting = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint)));

    try
    {
        NativeMethods.JidaVgaGetContrast(_handleJida, pdwSetting);
        var contrast = *(uint*)pdwSetting;
    }
    finally
    {
        Marshal.FreeHGlobal(pdwSetting);
    }
}

注意,C++函数指针类似

void (*GetContrastPointer)(HANDLE handle, unsigned int* setting);
可以作为

[DllImport("*.dll")]
void GetContrast(IntPtr handle, IntPtr setting); // most probably what you did
但也作为

[DllImport("*.dll")]
void GetContrast(IntPtr handle, ref uint setting);
这样您就可以像这样编写代码

uint contrast = 0; // or some other invalid value
NativeMethods.JidaVgaGetContrast(_handleJida, ref contrast);


这在性能和可读性方面都很好。

您能提供示例代码供我们参考吗?您能提供示例代码供我们参考吗?这似乎有效,但我不确定,因为由于硬件限制,当前本机方法将始终返回0。一旦我能够测试它,我会发回。@Davio-什么硬件限制?@Ramhound我相信他的意思是他的本机库在这个时候总是返回0(由于某些限制)-因此他无法使用大于int.MaxValue的值测试他的库。我说得对吗?@ananthonline你说得对。其中一根导线的焊接方式导致当前对比度设置不正确,因此它将始终返回0。这似乎可行,但我不确定,因为由于硬件限制,当前本机方法将始终返回0。一旦我能够测试它,我会发回。@Davio-什么硬件限制?@Ramhound我相信他的意思是他的本机库在这个时候总是返回0(由于某些限制)-因此他无法使用大于int.MaxValue的值测试他的库。我说得对吗?@ananthonline你说得对。其中一根导线的焊接方式导致电流对比度设置不正确,因此它总是返回0。我完全忘记了ref,我真傻。这就是我的结局,谢谢。我已经完全忘记了裁判,我真是太傻了。这就是我的结论,谢谢。但是正值也会有相同的值,这是错误的,因为初始的int读数是错误的。不,上面的代码就是你想要的。你在这里有点困惑。此代码的行为方式与您接受的答案中的不安全代码完全相同。好的,我认为像101这样的值作为uint读取时为5,使用ReadInt32读取时为-1,并且转换-1将给出您写下的高值,而不是我要找的5。在某种程度上,我认为它会错误地将高阶位读作符号,但@Davio它确实将高阶位读作符号位。但未设置0的高位。
(uint)
强制转换只是将位模式重新解释为
uint
。无论如何,根据您公认的答案,使用带有
ref uint
的重载是解决问题的最佳方法。但是
(unit)
cast是一种惯用的方式,可以精确地完成你在问题中提出的问题。所以,我想我回答了你提出的直接问题,但你接受的答案是解决潜在问题的正确方法。通常这是一个微妙的区别!但是正值会有相同的值,这是错误的,因为初始的int读数是错误的。不,上面的代码就是你想要的。你在这里有点困惑。此代码的行为方式与您接受的答案中的不安全代码完全相同。好的,我认为像101这样的值作为uint读取时为5,使用ReadInt32读取时为-1,并且转换-1将给出您写下的高值,而不是我要找的5。在某种程度上,我认为它会错误地将高阶位读作符号,但@Davio它确实将高阶位读作符号位。但未设置0的高位。
(uint)
强制转换只是将位模式重新解释为
uint
。无论如何,根据您公认的答案,使用带有
ref uint
的重载是解决问题的最佳方法。但是
(unit)
cast是一种惯用的方式,可以精确地完成你在问题中提出的问题。所以,我想我回答了你提出的直接问题,但你接受的答案是解决潜在问题的正确方法。通常这是一个微妙的区别!