c# - 仅在 Vista/Windows Server 2008 上出现 P/Invoke 错误

标签 c# windows-server-2008 pinvoke

我的代码通过 P/Invoke 使用 SSPI dll (security.dll) 中的方法,它在每个测试平台(Windows XP、Windows Server 2003 x86 和 x64)上都运行良好,但我们正在处理中迁移到 Windows Server 2008,并发现 P/Invoke 调用使进程崩溃。

我整理了以下重现代码:

using System;
using System.Runtime.InteropServices;

namespace TestPInvoke
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // The following code works on all platforms tested (Windows Server 2003 x86/x64, Windows Server 2008 x64, Windows XP, Windows Vista)
                var table1 = (SecurityFunctionTable)Marshal.PtrToStructure(InitReturningPtr(), typeof(SecurityFunctionTable));
                Console.WriteLine(table1.dwVersion);
                Console.WriteLine(table1.EnumerateSecurityPackages.ToInt64().ToString("x16"));
                Console.ReadLine();

                // This call crashes only on Windows Server 2008 and Windows Vista (but works fine on XP and 2K3)
                var table2 = InitReturningClass();
                Console.WriteLine(table2.dwVersion);
                Console.WriteLine(table2.EnumerateSecurityPackages.ToInt64().ToString("x16"));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
            Console.ReadLine();
        }

        [DllImport("security.dll", EntryPoint = "InitSecurityInterfaceW")]
        public static extern IntPtr InitReturningPtr();

        [DllImport("security.dll", EntryPoint = "InitSecurityInterfaceW")]
        public static extern SecurityFunctionTable InitReturningClass();

        [StructLayout(LayoutKind.Sequential)]
        public class SecurityFunctionTable
        {
            public uint dwVersion;
            public IntPtr EnumerateSecurityPackages;
            public IntPtr QueryCredentialsAttributes;
            // ...omitted for brevity
        }
    }
}

问题并不孤立于这个特定的 DLL 或函数,但我尝试过的任何 P/Invoke 调用都显示了问题,其中 native 函数的返回值是指向隐式编码到类中的结构的指针.

因为我有一个功能性的解决方法(使用 Marshal.PtrToStructure),这不是一个主要问题,但我很想知道为什么它在 XP 和 2k3 上没有(明显的)问题,但在 Vista 和 2k8 上却没有,并且是否有任何方法可以修复类返回方法以避免更丑陋的显式编码。

最佳答案

使用 Marshal.PtrToStructure正确的做法。这在 XP/Server 2003 上运行的事实纯属巧合,因为代码一直存在错误。

关于c# - 仅在 Vista/Windows Server 2008 上出现 P/Invoke 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3284408/

相关文章:

visual-studio-2012 - webdeploying时创建自动备份

asp.net - 安装 MS Web Deploy 3.0 - 无法启动 WMService

c# - UI 自动化的 Google Chrome 可访问树缓存问题

c# - 在 C# 中使用全局热键进行键捕获

c# - 使用数组填充列表框?

batch-file - 将标准输出重定向到屏幕和文本文件

c# - 如何将数据从托管程序集流式传输到 native 库并再次返回?

C# 精简多指针的内存读取

c# - 单步执行和跨过时函数的行为不同

c# - 未分配的属性会占用类中的内存吗?