C#中是否允许返回blittable结构体的解引用指针

问题描述 投票:0回答:1

是否可以/允许从这样的 C# pinvoke 代码返回结构体的取消引用指针。 该结构是 blittable 的。 Pinvoke 代码和结构是使用 CsWin32 生成的。感谢您提供与此相关的任何帮助:)

  internal static unsafe IEnumerable<ENUM_SERVICE_STATUS_PROCESSW> GetAllServices(this CloseServiceHandleSafeHandle serviceManagerHandle, string? group)
    {
        ArgumentNullException.ThrowIfNull(serviceManagerHandle);

        var data = new List<ENUM_SERVICE_STATUS_PROCESSW>();
        var serviceManagerHandleAddRef = false;
        try
        {
            serviceManagerHandle.DangerousAddRef(ref serviceManagerHandleAddRef);

            bool moreData;
            uint bytesNeeded = 0, resumeHandle = 0, servicesReturned = 0;
            do
            {
                moreData = false;
                var bufferData = new byte[bytesNeeded];
                fixed (byte* ptrBufferData = bufferData)
                {
                    fixed (char* ptrGroup = group)
                    {
                        if (!PInvokeCore.EnumServicesStatusEx((SC_HANDLE)serviceManagerHandle.DangerousGetHandle(), SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, ENUM_SERVICE_TYPE.SERVICE_WIN32_OWN_PROCESS, ENUM_SERVICE_STATE.SERVICE_STATE_ALL, ptrBufferData, (uint)bufferData.Length, &bytesNeeded, &servicesReturned, &resumeHandle, ptrGroup))
                        {
                            if (Marshal.GetLastPInvokeError() != (uint)WIN32_ERROR.ERROR_MORE_DATA)
                                throw new Exception($"Could not enumerate services. {Marshal.GetLastPInvokeErrorMessage()}");
                            else
                                moreData = true;
                        }
                    }

                    for (var i = 0; i < servicesReturned; i++)
                    {
                        ENUM_SERVICE_STATUS_PROCESSW element = ((ENUM_SERVICE_STATUS_PROCESSW*)ptrBufferData)[i];
                        data.Add(element);
                    }
                }
            } while (moreData);
        }
        finally
        {
            if (serviceManagerHandleAddRef)
                serviceManagerHandle.DangerousRelease();
        }

        return data;
    }

它可以工作,但我不确定这是否是非法操作。

c# pointers winapi pinvoke
1个回答
0
投票

答案是否定的,它不是保存返回结构体。结构本身是一个副本,因此可以安全返回,但结构中是一个 PWSTR 又名 char* ,并且该指针指向 byte* 中的一个区域(就在结构数组之后),该区域在函数返回后无效.

© www.soinside.com 2019 - 2024. All rights reserved.