Skip to content
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

Allow generating structs with inner struct properties staying .NET references instead of pointers (optimally only for some methods) #1003

Closed
drauch opened this issue Jul 27, 2023 · 3 comments
Labels
enhancement New feature or request

Comments

@drauch
Copy link

drauch commented Jul 27, 2023

Describe the solution you'd like
I'd like to write code like the following:

var myStruct = CreateStruct();
PInvoke.MyMethod(..., myStruct, ...);
[...]
OUTER_STRUCT CreateStruct ()
{
    INNER_STRUCT is;
    // fill is

    OUTER_STRUCT os;
    // fill os
    os.Inner = &is; // unfortunately pointer type instead of a C# reference type

    return os;
}

That doesn't work though, as the address &is is invalid once I return from CreateStruct.

Is your feature request related to a problem? Please describe.
I'm frustrated when I can't write it like that but instead have to write code like the following as a workaround:

var disposers = new List<Action>();
try
{
    var myStruct = CreateStruct(disposers);
    PInvoke.MyMethod(..., myStruct, ...);
}
finally
{
    foreach(var disposer in disposers)
        disposer();
}

[...]
OUTER_STRUCT CreateStruct (List<Action> disposers)
{
    INNER_STRUCT is;
    // fill is
    INNER_STRUCT* isPinned = GCHandle.Alloc(is, GCHandleType.Pinned);
    disposers.Add(() => isPinned.Free());

    OUTER_STRUCT os;
    // fill os
    os.Inner = (INNER_STRUCT*) is.AddrOfPinnedObject();

    return os;
}

Describe alternatives you've considered
None so far.

Additional context
See also discussion around #1002 (comment)

Best regards,
D.R.

@drauch drauch added the enhancement New feature or request label Jul 27, 2023
@AArnott
Copy link
Member

AArnott commented Jul 27, 2023

Can you give a concrete example of a pair of structs that are problematic for you so we can test the solution?

@drauch
Copy link
Author

drauch commented Jul 27, 2023

Here are some examples from my current SignerSignEx2 call:

  • SIGNER_SUBJECT_INFO & SIGNER_FILE_INFO
  • SIGNER_CERT & SIGNER_CERT_STORE_INFO
  • SIGNER_SIGNATURE_INFO & SIGNER_ATTR_AUTHCODE

Best regards,
D.R.

@AArnott
Copy link
Member

AArnott commented Jul 28, 2023

Oh, those all use explicit layout unions, so either C# or the runtime will likely not allow what you're asking for. Can you try declaring the structs yourself with the proposed modifications and see if it works? You can start by copying out the CsWin32 generated ones into your own code. If you use the same namespace and type names, CsWin32 will gracefully stop emitting the types that you yourself define.

@AArnott AArnott closed this as not planned Won't fix, can't repro, duplicate, stale Aug 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants