c# - 你能放心地说这个代码是 "unsafe"

标签 c# pinvoke

这是实现 native pinvok 代码的类

代码似乎可以工作,尽管我无法验证它是否正确使用不安全

签名不安全

    struct IO_COUNTERS
    {
        public ulong ReadOperationCount;
        public ulong WriteOperationCount;
        public ulong OtherOperationCount;
        public ulong ReadTransferCount;
        public ulong WriteTransferCount;
        public ulong OtherTransferCount;
    }
    [DllImport("kernel32.dll")]
    unsafe static extern bool GetProcessIoCounters(IntPtr* ProcessHandle, out IO_COUNTERS IoCounters);

带有“不安全”的代码

        public static unsafe class IO
        {
            public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
                GetProcessIoCounters((IntPtr*)System.Diagnostics.Process.GetCurrentProcess().Handle, out counters);
                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
                retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
                retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
                retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
                retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
                return retCountIoDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        }

现在,我的另一个问题中建议了下一个代码块(就在我设法编译并运行上面的代码之前,...因为我遇到了一些问题)

所以就在我通过反复试验解决了我的问题之后,有人发布了这个部分解决方案,这是部分原因,它不包括两者 structsigneture,所以我问它是否正在测试,因为它确实编译但不运行。 我的意思是当它运行时(没有编译错误)但在运行时,错误是

An exception of type 'System.NullReferenceException' occurred in App_Code.1ri3mog1.dll but was not handled in user code

其他信息:未将对象引用设置为对象的实例。

这是我从上一个问题中得到的代码

Ok you need to change a few things, shown below

public static class IO
{
    unsafe public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
    {
        IO_COUNTERS* counters;
        Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
        IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;

        GetProcessIoCounters(&ptr, out counters);
        retCountIoDict.Add("ReadOperationCount", counters->ReadOperationCount);
        retCountIoDict.Add("WriteOperationCount", counters->WriteOperationCount);
        retCountIoDict.Add("OtherOperationCount", counters->OtherOperationCount);
        retCountIoDict.Add("ReadTransferCount", counters->ReadTransferCount);
        retCountIoDict.Add("WriteTransferCount", counters->WriteTransferCount);
        retCountIoDict.Add("OtherTransferCount", counters->OtherTransferCount);
        return retCountIoDict;
        //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
        //    " Mb of data.";

    }
}

所以问题是,我是否真的做到了......并安全地使用了不安全的代码(顶部的代码块) 或者我错过了一些东西,如果我的代码没问题(我仍然怀疑它没有完全使用不安全的设备),建议的代码版本有什么问题?

最佳答案

您的代码已严重损坏。您的 GetProcessIoCounters 声明是错误的。您正在传递进程句柄的地址,但需要按值传递进程句柄。更重要的是,这里根本不需要不安全代码。我建议您停止使用不安全

以下是声明 GetProcessIoCounters 的方法:

[DllImport(@"kernel32.dll", SetLastError=true)]
static extern bool GetProcessIoCounters(
    IntPtr hProcess, 
    out IO_COUNTERS IoCounters
);

您的 IO_COUNTERS 声明没问题。

要调用该函数,您只需执行以下操作:

IO_COUNTERS IoCounters;
if (!GetProcessIoCounters(Process.GetCurrentProcess().Handle, out IoCounters))
    throw new Win32Exception();

关于c# - 你能放心地说这个代码是 "unsafe",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17212159/

相关文章:

c# - DwmGetWindowAttribute 使用 PInvoke 返回 0

c# - 在 RichTextBox C# WPF 中设置插入符位置

c# - 将事件传递给 ViewModel 的最佳方式是什么?

.NET 编码速度

c# - 通过 SendMessage 将字符串从 C# 发送到 MFC

c# - 如何使用正确的参数类型从 C# 正确调用 C++ DLL

c# - 从 C# 调用 Delphi DLL 函数

c# - 如何在进一步处理之前检查列表中的任何空值?

c# - 在c#中将cp1252字符串编码为utf-8字符串

c# - 将两条短裤放入字节数组