Jump to content

How to pass optional null terminated named arguments with dllcall


Recommended Posts

Hi all,

Hoping someone out there can help!

I'm looking at Libvips C API, seeing if it can be used with Autoit.

https://libvips.github.io/libvips/API/current/

I downloaded the binaries from:

https://github.com/libvips/libvips/releases/download/v8.9.2/vips-dev-w64-web-8.9.2.zip

 

I've come across an issue I can't figure out 😞

For optional parameters they use 'NULL-terminated list of optional named arguments'

Anyone know if named arguments can be passed with Autoit's dllcall()?

 

Many thanks in advance.

 

This is the test code I'm using, trying to get sharpening to work. It works with no optional arguments, defaults only.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****


#include <Array.au3>
#include <WinAPIMem.au3>

Global $__g_hLibVipsDll = DllOpen('libvips-42.dll')
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $__g_hLibVipsDll = ' & $__g_hLibVipsDll & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

_VIPS_Init()

Global $g_pVipsImg = _VIPS_Image_New_From_File(@ScriptDir & '\test.jpg')

Global $g_pVipsImgResized = _VIPS_Resize($g_pVipsImg, 0.2)
Global $g_pVipsImgSharpened = _VIPS_Sharpen($g_pVipsImgResized)

DirCreate(@DesktopDir & '\test')
_VIPS_Image_Write_To_File($g_pVipsImgResized, @DesktopDir & '\test\VIPS_Resized.jpg')
_VIPS_Image_Write_To_File($g_pVipsImgSharpened, @DesktopDir & '\test\VIPS_Sharpened.jpg')

_VIPS_Shutdown()

DllClose($__g_hLibVipsDll)


Func _VIPS_Sharpen($hVipsImg)

    ;sigma == 0.5
    ;x1 == 2
    ;y2 == 10         (don't brighten by more than 10 L*)
    ;y3 == 20         (can darken by up to 20 L*)
    ;m1 == 0          (no sharpening in flat areas)
    ;m2 == 3          (some sharpening in jaggy areas)

;~  Local $tArgs = DllStructCreate('align 1;struct;char Nsigma[5];double Vsigma;char null;endstruct')
;~  $tArgs.Nsigma = 'sigma'
;~  $tArgs.Vsigma = 0.5


    Local $pArgs = _WinAPI_CreateString('sigma', 0, -1, False)

;~  Local $aRet = DllCall($__g_hLibVipsDll, 'int', 'vips_sharpen', 'ptr', $hVipsImg, 'ptr*', Null, 'str', 'sigma', 'double', 1.0, 'str', Null)
    Local $aRet = DllCall($__g_hLibVipsDll, 'int', 'vips_sharpen', 'ptr', $hVipsImg, 'ptr*', Null, 'ptr', $pArgs, 'double', 0.7, 'str', Null)

;Passing no optional arguments works with defaults
;~  Local $aRet = DllCall($__g_hLibVipsDll, 'int', 'vips_sharpen', 'ptr', $hVipsImg, 'ptr*', Null, 'str', Null)


    _ArrayDisplay($aRet, 'Sharpen')
    _WinAPI_FreeMemory($pArgs)

    Return $aRet[2]

EndFunc



Func _VIPS_Resize($hVipsImg, $fScale)

    Local $aRet = DllCall($__g_hLibVipsDll, 'int', 'vips_resize', 'ptr', $hVipsImg, 'ptr*', Null, 'double', $fScale, 'str', Null)
    If @error Then Return SetError(@error, 0, 0)
    Return $aRet[2]

EndFunc



Func _VIPS_Image_New_From_File($sFile);, $iAccess = 1, $bMemory = True)

    Local $aRet = DllCall($__g_hLibVipsDll, 'ptr', 'vips_image_new_from_file', 'str', $sFile, 'str', Null)
    If @error Then Return SetError(@error, 0, 0)
    Return $aRet[0]

EndFunc



Func _VIPS_Image_Write_To_File($hVipsImg, $sFile)

    Local $aRet = DllCall($__g_hLibVipsDll, 'int', 'vips_image_write_to_file', 'ptr', $hVipsImg, 'str', $sFile, 'str', Null)
    If @error Then Return SetError(@error, 0, 0)
    Return $aRet[0]

EndFunc



Func _VIPS_Init($sName = @ScriptName)

    Local $aRet = DllCall($__g_hLibVipsDll, 'int', 'vips_init', 'str', $sName)
    If @error Then Return SetError(@error, 0, 0)
    Return $aRet[0] = 0 ? 1 : 0

EndFunc



Func _VIPS_Shutdown($sName = @ScriptName)

    Local $aRet = DllCall($__g_hLibVipsDll, 'NONE', 'vips_shutdown')
    If @error Then Return SetError(@error, 0, 0)
    Return $aRet[0] = 0 ? 1 : 0

EndFunc

 

 

 

 

 

 

Link to comment
Share on other sites

I've had some success :)

Seems my early attempt to pair the arguments in the dllcall was correct but for one annoying anomaly!!

Seems the first name/value pair is always zero??!!

Because I was testing with sigma this caused an error as sigma was out of range.

I've move a value that always expect to be zero to the first place, every else works as it should after that.

No idea what's going on but at least I'm getting the result I want.

Func _VIPS_Sharpen($hVipsImg)

    ;sigma == 0.5
    ;x1 == 2          (threshold)
    ;y2 == 10         (don't brighten by more than 10 L*)
    ;y3 == 20         (can darken by up to 20 L*)
    ;m1 == 0          (no sharpening in flat areas)
    ;m2 == 3          (some sharpening in jaggy areas)**Adjust this to change sharpness intensity


    Local $aRet = DllCall($__g_hLibVipsDll, 'int', 'vips_sharpen', 'ptr', $hVipsImg, 'ptr*', Null, _
                                'str', 'm1', 'double', 0, _
                                'str', 'sigma', 'double', 2, _
                                'str', 'x1', 'double', 2, _
                                'str', 'y2', 'double', 10, _
                                'str', 'y3', 'double', 20, _
                                'str', 'm2', 'double', 10, _
                                'str', Null)


    Return $aRet[2]

EndFunc

 

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...