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

Function with output pointer parameters #1381

Open
PeterDraex opened this issue Jun 12, 2020 · 3 comments
Open

Function with output pointer parameters #1381

PeterDraex opened this issue Jun 12, 2020 · 3 comments

Comments

@PeterDraex
Copy link

PeterDraex commented Jun 12, 2020

Brief Description

I'm trying to generate wrapper for the following function:

HRESULT
WINAPI
WebAuthNAuthenticatorGetAssertion(
    _In_        HWND                                                hWnd,
    _In_        LPCWSTR                                             pwszRpId,
    _In_        PCWEBAUTHN_CLIENT_DATA                              pWebAuthNClientData,
    _In_opt_    PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS      pWebAuthNGetAssertionOptions,
    _Outptr_result_maybenull_ PWEBAUTHN_ASSERTION                   *ppWebAuthNAssertion);

As you see, this function has out parameter of type PWEBAUTHN_ASSERTION*.

The following managed code is generated for this function:

public static int WebAuthNAuthenticatorGetAssertion(
   global::System.IntPtr hWnd,
   string pwszRpId,
   global::WebAuthN.WEBAUTHN_CLIENT_DATA pWebAuthNClientData,
   global::WebAuthN.WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS pWebAuthNGetAssertionOptions,
   global::WebAuthN.WEBAUTHN_ASSERTION ppWebAuthNAssertion)
{
    var __arg0 = (IntPtr)hWnd;
    var __arg2 = ReferenceEquals(pWebAuthNClientData, null) ? global::System.IntPtr.Zero : pWebAuthNClientData.__Instance;
    var __arg3 = ReferenceEquals(pWebAuthNGetAssertionOptions, null) ? global::System.IntPtr.Zero : pWebAuthNGetAssertionOptions.__Instance;
    var ____arg4 = ReferenceEquals(ppWebAuthNAssertion, null) ? global::System.IntPtr.Zero : ppWebAuthNAssertion.__Instance;
    var __arg4 = new global::System.IntPtr(&____arg4);
    var __ret = __Internal.WebAuthNAuthenticatorGetAssertion(__arg0, pwszRpId, __arg2, __arg3, __arg4);
    return __ret;
}

As you see, the output parameter generates parameter of class-type WEBAUTHN_ASSERTION.

Call of this function works, but when I try to access the output object, System.AccessViolationException is thrown.

What would be the correct type of this output parameter in generated code?
How can that be achieved?

OS: Windows 10 64-bit

Used headers

https://github.com/microsoft/webauthn/blob/master/webauthn.h

Used settings

Target: MSVC/GCC/Clang

Other settings:

driver.ParserOptions.ForceClangToolchainLookup = true;
driver.ParserOptions.Verbose = true;
var options = driver.Options;
options.GeneratorKind = GeneratorKind.CSharp;
options.Verbose = true;
@tritao
Copy link
Collaborator

tritao commented Jun 12, 2020

You should also include the function body of the generated code, so we can look at how its being marshalled.

Anyway, since this is an out parameter, you could try something like:

ctx.FindFunction("WebAuthNAuthenticatorGetAssertion").First().FindParameter("ppWebAuthNAssertion").Usage = ParameterUsage.Out;

Or use SetFunctionParameterUsage , see

public static void SetFunctionParameterUsage(this ASTContext context,
.

@PeterDraex
Copy link
Author

@tritao

I've tried adding your suggestions to Preprocess(). They both result in this code:

        public static int WebAuthNAuthenticatorGetAssertion(global::System.IntPtr hWnd, string pwszRpId, global::WebAuthN.WEBAUTHN_CLIENT_DATA pWebAuthNClientData, global::WebAuthN.WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS pWebAuthNGetAssertionOptions, out global::WebAuthN.WEBAUTHN_ASSERTION ppWebAuthNAssertion)
        {
            var __arg0 = (IntPtr)hWnd;
            var __arg2 = ReferenceEquals(pWebAuthNClientData, null) ? global::System.IntPtr.Zero : pWebAuthNClientData.__Instance;
            var __arg3 = ReferenceEquals(pWebAuthNGetAssertionOptions, null) ? global::System.IntPtr.Zero : pWebAuthNGetAssertionOptions.__Instance;
            var ____arg4 = ReferenceEquals(ppWebAuthNAssertion, null) ? global::System.IntPtr.Zero : ppWebAuthNAssertion.__Instance;
            var __arg4 = new global::System.IntPtr(&____arg4);
            var __ret = __Internal.WebAuthNAuthenticatorGetAssertion(__arg0, pwszRpId, __arg2, __arg3, __arg4);
            return __ret;
        }

The compiler has two problems with this code:

  • use of unassigned out parameter ppWebAuthNAssertion, on line with ____arg4
  • output parameter must be assigned, on line with return

Any ideas?

@PeterDraex
Copy link
Author

The following code works correctly!

public static int WebAuthNAuthenticatorGetAssertion(global::System.IntPtr hWnd, string pwszRpId, global::WebAuthN.WEBAUTHN_CLIENT_DATA pWebAuthNClientData, global::WebAuthN.WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS pWebAuthNGetAssertionOptions, out global::WebAuthN.WEBAUTHN_ASSERTION ppWebAuthNAssertion)
{
    var __arg0 = (IntPtr)hWnd;
    var __arg2 = ReferenceEquals(pWebAuthNClientData, null) ? global::System.IntPtr.Zero : pWebAuthNClientData.__Instance;
    var __arg3 = ReferenceEquals(pWebAuthNGetAssertionOptions, null) ? global::System.IntPtr.Zero : pWebAuthNGetAssertionOptions.__Instance;
    var __ret = __Internal.WebAuthNAuthenticatorGetAssertion(__arg0, pwszRpId, __arg2, __arg3, out IntPtr __arg4); // requires addition of "out" to method header

    ppWebAuthNAssertion = global::WebAuthN.WEBAUTHN_ASSERTION.__CreateInstance(__arg4);

    return __ret;
}

Now the question is, how to get CppSharp, to generate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants