-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug? PEBCAK? Unable to initialize __nuint_1 to user-defined length #873
Comments
The problem is CsWin32 doesn't recognize this as a variable length array, so it just uses a fixed 1-length array. See #387, which tracks improving the usability of this case. As a workaround, assuming the struct is initialized elsewhere, you can access the full list like this: JOBOBJECT_BASIC_PROCESS_ID_LIST list;
unsafe
{
Span<nuint> pids = new(&list.ProcessIdList._0, (int)list.NumberOfProcessIdsInList);
for (int i = 0; i < pids.Length; i++)
{
Console.WriteLine(pids[i]);
}
} But if you need to initialize the list, you'll have to allocate enough memory for the struct, and then pin the struct at that location yourself. I can provide sample code for that if you need. |
Yes, I got this far, which seems to work, but might not be the most efficient.
|
JOBOBJECT_BASIC_PROCESS_ID_LIST idList = *pidList;
var ids = idList.ProcessIdList.AsReadOnlySpan(); This is broken for two reasons: I'm preparing a sample of what I believe should work. |
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.JobObjects;
unsafe
{
HANDLE hJob = default;
const int MaxProcessCount = 4096; // TODO: pick a good number here
int MemorySize = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + MaxProcessCount * sizeof(nuint);
fixed (byte* pBytes = new byte[MemorySize])
{
JOBOBJECT_BASIC_PROCESS_ID_LIST* pList = (JOBOBJECT_BASIC_PROCESS_ID_LIST*)pBytes;
uint returnLength = 0;
PInvoke.QueryInformationJobObject(hJob, JOBOBJECTINFOCLASS.JobObjectBasicProcessIdList, pList, (uint)MemorySize, &returnLength);
Span<nuint> pids = new(&pList->ProcessIdList, (int)pList->NumberOfProcessIdsInList);
for (int i = 0; i < pids.Length; i++)
{
Console.WriteLine(pids[i]);
}
}
} I'm using memory allocated from the GC heap so that you don't have to worry about a |
Thank you very much, Andrew. I'll give that a go. Update: Yep, works great. Thanks again! |
Actual behavior
Full disclosure: I am probably missing something or do not know how to do something (although, I have spent the day reading and researching and testing).
When calling an API and passing a structure which contains a variable array, CsWin32 generates a
struct
that has a member of type__nuint_1
. However, I see no way to set the__nuint_1
'sSpanLength
so that it allocates a specific number of elements.Expected behavior
It seems that
__nuint_1
should have a way to initialize it to have a user-specified number of elements, since we have to pass the size of the memory block to the function.Repro steps
NativeMethods.txt
content:Generated:
Context
0.2.188-beta
.NET 7
LangVersion
(if explicitly set by project):latest (C# 11)
The text was updated successfully, but these errors were encountered: