标签: intptr

在C#中赢得api.从IntPtr获取高低字

我试图在C#中处理WM_MOUSEMOVE消息.

从lParam获取X和Y坐标的正确方法是什么?这是一种IntPtr?

c# winapi intptr

13
推荐指数
2
解决办法
1万
查看次数

C#Process.MainWindowHandle始终返回IntPtr Zero

这是我的代码:

            using (Process game = Process.Start(new ProcessStartInfo() { 
        FileName="DatabaseCheck.exe",
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        UseShellExecute = false }))
        {
            lblLoad.Text = "Loading";
            int Switch = 0;

            while (game.MainWindowHandle == IntPtr.Zero)
            {
                Switch++;
                if (Switch % 1000 == 0)
                {
                    lblLoad.Text += ".";
                    if (lblLoad.Text.Contains("...."))
                        lblLoad.Text = "Loading.";

                    lblLoad.Update();
                    game.Refresh();
                }
            }
Run Code Online (Sandbox Code Playgroud)

问题是,那个游戏.MainWindowHandle总是IntPtr.Zero.我需要找到运行过程的IntPtr以确认游戏是由启动器启动的,所以我让游戏发送它的IntPtr并让启动器响应它是否正常.但为此,我必须具体了解运行过程的IntPtr.

提前致谢!

c# process window-handles intptr

12
推荐指数
3
解决办法
2万
查看次数

在C#中使用正确的IntPtr

我理解IntPtr的使用,虽然我真的不确定.

我从MSDN复制IDisposable模式只是为了看看我能从中得到什么,虽然我在大多数情况下理解它,但我不知道如何正确实现IntPtr,或者甚至不知道它应该"指向什么" "参考或参考.最重要的是,我不知道如何为IntPtr分配或转换整数,字符串,字符,双精度等来创建指针.

此外,IntPtr是否需要使用不安全的代码?

无论如何,这里有一些代码只是为了描绘我正在谈论的内容:

namespace Utilities
{   
    class Disposer : IDisposable
    {

        private IntPtr handle;

        private Component component = new Component(); 

        private bool disposed = false;

        public Disposer(IntPtr handle)
        {
            this.handle = handle;

        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if(!this.disposed)
            {
                if (disposing)
                {
                    component.Dispose(); 
                }
                CloseHandle(handle);

                handle = IntPtr.Zero;

                disposed = true;

            }
        }

        [System.Runtime.InteropServices.DllImport("Kernal32")]
        private extern static Boolean CloseHandle(IntPtr handle);
    }



    public unsafe class ExecuteMain
    {
        Object …
Run Code Online (Sandbox Code Playgroud)

c# idisposable intptr

11
推荐指数
3
解决办法
2万
查看次数

从IntPtr获取struct数组

我有一些像这样的结构

struct MyStruct
{
    public int field1;
    public int field2;
    public int field3;
}
Run Code Online (Sandbox Code Playgroud)

我有指向此结构数组的指针.所以,我需要从这个指针获取数组.我试图使用Marshal.PtrToStructure,但我有内存读取错误.这是我的方法:

public MyStruct[] GetArrayOfStruct(IntPtr pointerToStruct, int length)
{
    var sizeInBytes = Marshal.SizeOf(typeof(TCnt));
    MyStruct[] output = new MyStruct[length];

    for (int i = 0; i < length; i++)
    {
        IntPtr p = new IntPtr((pointerToStruct.ToInt32() + i * sizeInBytes));

        output[i] = (MyStruct)System.Runtime.InteropServices.Marshal.PtrToStructure(p, typeof(MyStruct));
    }

    return output;
}
Run Code Online (Sandbox Code Playgroud)

那么,我做错了什么?

c# arrays marshalling intptr

11
推荐指数
2
解决办法
9417
查看次数

IntPtr和UIntPtr之间的区别

RegOpenKeyEx当我在页面上注意到这条评论时,我正在查看P/Invoke声明:

更改IntPtrUIntPtr:使用IntPtr句柄调用时,您将遇到溢出.UIntPtr如果您希望在32位和64位平台上正常工作,则是正确的选择.

这并没有太大的意义对我说:都IntPtrUIntPtr应该代表指针因此其大小应与OS的位数-无论是32位或64位.由于这些不是数字而是指针,因此它们的带符号数值应该无关紧要,只有表示它们指向的地址的位.我想不出为什么这两者之间会有什么不同,但是这个评论让我不确定.

是否有使用的具体原因UIntPtr而不是IntPtr?根据文件:

IntPtr类型是符合CLS,而UIntPtr类型不是.IntPtr在公共语言运行库中仅使用该类型.UIntPtr提供的类型主要是为了保持与IntPtr类型的架构对称性.

当然,这意味着没有区别(只要有人不尝试将值转换为整数).所以pinvoke.net的上述评论是错误的吗?

编辑:

在阅读了MarkH的回答之后,我做了一些检查,发现.NET应用程序不是大地址识别,并且在32位模式下编译时只能处理2GB的虚拟地址空间.(可以使用hack打开大地址识别标志,但MarkH的答案显示.NET Framework内的检查会破坏因为地址空间仅为2GB,而不是3GB.)

这意味着指针可以拥有的所有正确的虚拟内存地址(就.NET Framework而言)将介于0x00000000和0x7FFFFFFF之间.当此范围转换为有符号时int,没有值为负值,因为未设置最高位.这强化了我的信念,即使用IntPtr与UIntPtr没有区别.我的推理是否正确?

Fermat2357指出上面的编辑是错误的.

.net c# pointers intptr

11
推荐指数
1
解决办法
6085
查看次数

IntPtr转换为string.Format中的十六进制字符串

请注意,我不太确定这个问题属于这个网站,但我尝试建设性的.

为什么代码

IntPtr ptr = new IntPtr(1234);
Console.WriteLine(string.Format("{0:X8}", ptr));
Console.WriteLine(ptr.ToString("X8"));
Console.WriteLine(string.Format("{0:X8}", ptr.ToInt32()));
Run Code Online (Sandbox Code Playgroud)

产量

1234
000004D2
000004D2
Run Code Online (Sandbox Code Playgroud)

为什么IntPtr在格式化时请求将十六进制格式直接应用于参数?有没有任何已知的论据反对设计功能 - ?
如果没有针对此类设计的论据,那么我应该通过哪个渠道向Microsoft报告此问题?


另请注意,IntPtr如果请求,调试器将以十六进制显示值.
我发现打印输出IntPtr值非常直观且相对频繁.我也找到了使用第一行的其他人编写的代码,显然期望十六进制结果,但实际上结果是不同的.我也花了一些时间来注意这个问题,这使得理解日志消息更加复杂.

c# hex tostring intptr

11
推荐指数
2
解决办法
6973
查看次数

.NET Interop IntPtr与ref

可能是一个菜鸟问题,但互操作不是我的优点之一.

除了限制重载次数之外,有任何理由我应该声明我的DllImports:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
Run Code Online (Sandbox Code Playgroud)

并像这样使用它们:

IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(formatrange));
Marshal.StructureToPtr(formatrange, lParam, false);

int returnValue = User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_FORMATRANGE, wParam, lParam);

Marshal.FreeCoTaskMem(lParam);
Run Code Online (Sandbox Code Playgroud)

而不是创建目标重载:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref FORMATRANGE lParam);
Run Code Online (Sandbox Code Playgroud)

使用它像:

FORMATRANGE lParam = new FORMATRANGE();
int returnValue = User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_FORMATRANGE, wParam, ref lParam);
Run Code Online (Sandbox Code Playgroud)

by ref重载最终更容易使用,但我想知道是否存在我不知道的缺点.

编辑:

到目前为止,有很多很棒的信息.

@P爸爸:你有一个基于抽象(或任何)类的结构类的例子吗?我将签名改为:

[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, [In, …
Run Code Online (Sandbox Code Playgroud)

.net c# winapi interop intptr

10
推荐指数
1
解决办法
1万
查看次数

将指针数组转换为IntPtr数组

我陷入了一项看似微不足道的任务,需要你的帮助.

我需要编写一个带有以下签名的方法:

System.Array ToIntPtrArray(System.Array a)
Run Code Online (Sandbox Code Playgroud)

其中一个实际的参数可以是任意的阵列指针类型(例如int*[],long**[],void*[,]),并用类型的元素返回相同形状的阵列System.IntPtr具有相同的数值作为输入数组的元素.问题是如果我事先不知道它们的类型,我不明白如何提取指针的数值.


例如,如果我事先知道我的参数总是类型void*[],我可以编写如下方法:

unsafe IntPtr[] ToIntPtrArray(void*[] a)
{
    var result = new IntPtr[a.Length];
    for (int i = 0; i < a.Length; i++)
        result[i] = (IntPtr) a[i];

    return result;
}
Run Code Online (Sandbox Code Playgroud)

但问题是它可能不是void*[],但是void**[]或其他任何东西,该方法应该能够处理所有情况.

.net c# arrays pointers intptr

10
推荐指数
1
解决办法
2044
查看次数

如何获得窗口的位置?

我想知道获得进程窗口位置的方式.我一直在网上寻找,但没有结果.谢谢 :)

Process[] processes = Process.GetProcessesByName("notepad");
Process lol = processes[0];

IntPtr p = lol.MainWindowHandle;
Run Code Online (Sandbox Code Playgroud)

c# position window process intptr

9
推荐指数
1
解决办法
3万
查看次数

C#我可以检查IntPtr是否为空?

我的C#类中有一个IntPtr字段.
它包含对C++库中对象的引用.

protected IntPtr ThingPtr;
Run Code Online (Sandbox Code Playgroud)

在某些阶段,我可能会或可能不会初始化它.

ThingPtr = FunctionInMyCplusplusLibrary();
Run Code Online (Sandbox Code Playgroud)

我想知道在这种情况下检查是否为null是有意义的(检查它是否已被初始化)

if(ThingPtr == null)
{
    //Do stuff
}
Run Code Online (Sandbox Code Playgroud)

c# null intptr

9
推荐指数
1
解决办法
1万
查看次数