Jump to content

How to implement C function with parameters which contain functions


 Share

Recommended Posts

Consider the below C function

#pragma once

// Gets the CLR Version for a given PowerShell Version. PowerShell Version is
// supplied with 2 parameters iPSMajorVersion (PowerShell major version) and
// iPSMinorVersion (PowerShell minor version). The CLR version is returned through
// pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion.
// returns: 0 on success, non-zero on failure.
_Success_(return == 0)  // EXIT_CODE_SUCCESS
extern "C"
unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion,
                      int iPSMinorVersion,
                      size_t runtimeVersionLength,
                      __inout_ecount_part(runtimeVersionLength , *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion,
                      __out_ecount(1) size_t* pRuntimeVersionLength);

This function is contained within a C dll that I am trying to use in an autoit udf, but I am kind of hung up on the last two parameters in the function.  What confuses me about these parameters is that they both appear to have functions preceding the variable (these functions appear to be parameterized macros, as they are defined using the "#define" preprocessor in another header file in the project) and am not sure how to account for these functions when calling the GetCLRVersionForPSVersion function in Dllcall.  I had initially thought that maybe I could use a callback function to account for the function, but the function would still need to be its own parameter separated from the variable following it, right?  Any input concerning this would be very much appreciated.

Edited by MattHiggs
Link to comment
Share on other sites

Don't try to overthink it before first trying to use the information provided.  Keep it simple -- at least at first.  In this case, you don't need to know what those parts of the declaration mean.  All you really need to know about those odd declarations are the data types.  The description of the function that you provided states that the function only really requires 2 integer values for input.  It goes on to state that the result will be placed into a wchar buffer that you need to supply the pointer to and the size of that wchar buffer.

#include <Constants.au3>
#include <array.au3>
#include <WinAPIConv.au3>

Example_GetCLRVersionForPSVersion(2, 0)

Func Example_GetCLRVersionForPSVersion($iPsMajorVersion, $iPsMinorVersion)
    Local $aResult
    Local $tWcharBuffer


    ;Create wchar buffer to hold result
    $tWcharBuffer = DllStructCreate("wchar buffer[30];")

    ;Call function
    $aResult = DllCall("pwrshplugin.dll", "int:cdecl", "GetCLRVersionForPSVersion", _
                       "int",        $iPsMajorVersion, _
                       "int",        $iPsMinorVersion, _
                       "ulong_ptr",  DllStructGetSize($tWcharBuffer), _
                       "ptr",        DllStructGetPtr($tWcharBuffer), _
                       "ulong_ptr*", Null)
    If @error Then
        Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "DllCall failed - @error = " & @error)
    ElseIf _WinAPI_LoWord($aResult[0]) <> 0 Then ;HRESULT return code
        Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Bad return code from DllCall - RC = " & $aResult[0] & " (0x" & Hex($aResult[0]) & ")")
    EndIf

    _ArrayDisplay($aResult, "DllCall Result")

    ;Display the results
    ConsoleWrite("GetCLRVersionForPSVersion Example" & @CRLF)
    ConsoleWrite("PowerShell Version : " & "v" &$iPsMajorVersion & "." & $iPsMinorVersion & @CRLF)
    ConsoleWrite("CLR Runtime Version: " & ($tWcharBuffer.buffer = "" ? "PS Version Not Installed" : $tWcharBuffer.buffer) & @CRLF)
EndFunc

Console:

GetCLRVersionForPSVersion Example
PowerShell Version:  v2.0
CLR Runtime Version: v2.0.50727

 

Edited by TheXman
Added HRESULT return code check to script
Link to comment
Share on other sites

3 hours ago, MattHiggs said:

Consider the below C function


#pragma once

// Gets the CLR Version for a given PowerShell Version. PowerShell Version is
// supplied with 2 parameters iPSMajorVersion (PowerShell major version) and
// iPSMinorVersion (PowerShell minor version). The CLR version is returned through
// pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion.
// returns: 0 on success, non-zero on failure.
_Success_(return == 0)  // EXIT_CODE_SUCCESS
extern "C"
unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion,
                      int iPSMinorVersion,
                      size_t runtimeVersionLength,
                      __inout_ecount_part(runtimeVersionLength , *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion,
                      __out_ecount(1) size_t* pRuntimeVersionLength);

This function is contained within a C dll that I am trying to use in an autoit udf, but I am kind of hung up on the last two parameters in the function.  What confuses me about these parameters is that they both appear to have functions preceding the variable (these functions appear to be parameterized macros, as they are defined using the "#define" preprocessor in another header file in the project) and am not sure how to account for these functions when calling the GetCLRVersionForPSVersion function in Dllcall.  I had initially thought that maybe I could use a callback function to account for the function, but the function would still need to be its own parameter separated from the variable following it, right?  Any input concerning this would be very much appreciated.

Those macros are header annotations, and are used with visual studio etc, to insure functions are called correctly, they are not operative, and in this case can be safely ignored as shown by @TheXman.

more info: https://docs.microsoft.com/en-us/windows/win32/winprog/header-annotations

Code hard, but don’t hard code...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...