
swoop
Active Members-
Posts
33 -
Joined
-
Last visited
swoop's Achievements

Seeker (1/7)
3
Reputation
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
I peeked! Thanks for the guidance. I am very grateful. I'm going to apply your way. It's so much better than my first attempt. I see this particular use of DllOpen and DllClose to get a DLL Handle instead of using the DLL filename string in the helper functions. DllOpen($ZEROMG_DLL_FILE) and DllClose($ghZeroMQDll) That's more flexible than just using a global string constant for the filename. Getting the handle can also give an error message if the DLL is missing. Is the following code just added assurance that the DLL handle is closed upon exit? ;Register function to close dll handle on exit OnAutoItExitRegister("close_zmq_dll_handle") I see you also used handle instead of ptr for the $hContext. The handle type appears to be equivalent to void*. I made that mistake as well. Again, thanks for the help!
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
Good suggestion. I'll get the rest of the functions written and tested first. So, this usually occurs when scope of a function ends. If the data struct is in the global scope, the resources are freed upon exit of the script. Is that correct? I can just let AutoIt handle that garbage collection. Just curious, is there a way to free or destroy that data struct? Something like a _WinAPI_CopyStruct (Creates a duplicate of a specified structure), but for destroying a Struct? Nine said my somevarA = 0 doesn't actually free up that data.
-
TheXman reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
Sorry, my bad. I just caught my error in the second example for __CryptoNG_BCryptGetProperty. $tIVBuffer = DllStructCreate(StringFormat("byte data[%i]", $iBlockLength)) $tIVBuffer.data = $xIV This is actually creating the struct variable defined by StringFormat("byte data[%i]", $iBlockLength) So the struct is something like "byte data[10]" In this case, it is not an optional pointer.
-
@TheXman I have been studying the CryptoNG UDF and the HttpApi UDF. Thanks again for the suggestion and help. I want to clarify if I understand how DllStructs are used in AutoIt for working with external DLLs. In the help file about DllStructCreate: https://www.autoitscript.com/autoit3/docs/functions/DllStructCreate.htm the description reads as follows: DllStructCreate Creates a C/C++ style structure to be used in DllCall. DllStructCreate ( Struct [, Pointer] ) Parameters Struct A string representing the structure to create (See Remarks). Pointer [optional] If supplied the struct will not allocate memory but use the pointer supplied. Return Value Success: a variable for use with DllStruct calls. Failure: sets the @error flag to non-zero. @error: 1 = Variable passed to DllStructCreate was not a string. 2 = There is an unknown Data Type in the string passed. 3 = Failed to allocate the memory needed for the struct, or Pointer = 0. 4 = Error allocating memory for the passed string. When we have an existing struct created by another DLL, we don't need to create that struct again in memory. But it is important to use the DllStructCreate with the optional pointer parameter in order to work with this "external" struct in AutoIt. The variable returned from DllStructCreate is used by DllStruct and other DllCall related functions to deal with an unknown pre-existing struct. Such functions as: DllCall, DllStructGetData, DllStructGetPtr, DllStructGetSize, DllStructSetData, IsDllStruct. I refer to specific DllStructCreate examples in your UDF's for my current understanding: From the HTTPAPI.au3: Func _HTTPAPI_HttpSendHttpResponse($hRequestQueue, $iRequestId, $iStatusCode, $sReason, $sBody) _DebugOut(@CRLF & "Function: HttpSendHttpResponse") Local $aResult[0] Local $pKnownHeader = Null Local $iFlags = 0 Local $tResponse = DllStructCreate($__HTTPAPI_gtagHTTP_RESPONSE_V2), _ $tCachePolicy = DllStructCreate($__HTTPAPI_gtagHTTP_CACHE_POLICY), _ $tLoggedData = DllStructCreate($__HTTPAPI_gtagHTTP_LOG_FIELDS_DATA), _ $tDataChunk = DllStructCreate($__HTTPAPI_gtagHTTP_DATA_CHUNK_FROM_MEMORY), _ $tReason = __HTTPAPI_CreateStringBuffer($sReason), _ $tBody = __HTTPAPI_CreateStringBuffer($sBody), _ $tContentType = __HTTPAPI_CreateStringBuffer("text/html"), _ $tContentLength = __HTTPAPI_CreateStringBuffer(String(DllStructGetSize($tBody))), _ $tHeader = "" ;Init response $tResponse.MajorVersion = 1 $tResponse.MinorVersion = 1 $tResponse.StatusCode = $iStatusCode $tResponse.pReason = DllStructGetPtr($tReason) $tResponse.ReasonLength = DllStructGetSize($tReason) $tResponse.LogDataType = $__HTTPAPI_HttpLogDataTypeFields ;Add known header(s) to response $pKnownHeader = DllStructGetPtr($tResponse, "KnownHeaders") + ($__HTPPAPI_HttpHeaderContentType * $__HTTPAPI_HTTP_KNOWN_HEADER_SIZE) $tHeader = DllStructCreate($__HTTPAPI_gtagHTTP_KNOWN_HEADER, $pKnownHeader) $tHeader.pRawValue = DllStructGetPtr($tContentType) $tHeader.RawValueLength = DllStructGetSize($tContentType) The specific line 1240: $tHeader = DllStructCreate($__HTTPAPI_gtagHTTP_KNOWN_HEADER, $pKnownHeader) I think that means the $tHeader struct is not created nor allocated in memory. We're just creating a struct variable to work with the struct. $pKnownHeader is a pointer to a pre-existing struct (in memory). We are creating $tHeader DLLStruct variable that contains information about the existing struct, which we know has the structure defined by $__HTTPAPI_gtagHTTP_KNOWN_HEADER. This $tHeader variable allows for us to use DllStruct functions to call and manipulate data in the memory location referred by $pKnownHeader. To apply the same idea to my ZeroMQ Dll struct code, if the ZeroMQ DLL functions create existing message structs and gives me back pointers, then I can use the DllStructCreate to do the same as you've done above. To make the message structs available for use in AutoIt via DllStrut and DllCall functions. That's also what's happening in the CryptoNG when DllStructCreate is used in the __CryptoNG_BCryptDecrypt function. From the CryptoNG.au3: Func __CryptoNG_BCryptDecrypt($sAlgorithmId, $xData, $hEncryptionKey, $bResultIsText = True) Local $tInputBuffer = "", _ $tOutputBuffer = "", _ $tIVBuffer = "", _ $tByteBuffer = "", _ $tUlong = "" Local $iBlockLength = 0, _ $iStatusCode = 0, _ $iError = 0, _ $iOutputLength = 0 Local $aResult[0] Local $vDecryptedData = "" Local $xIV = Binary("") _DebugOut(@CRLF & "Function: __CryptoNG_BCryptDecrypt()") _DebugOut("$sAlgorithmId = " & $sAlgorithmId) _DebugOut("$xData = " & $xData) ;Get length of key $tByteBuffer = __CryptoNG_BCryptGetProperty($hEncryptionKey, $CNG_BCRYPT_KEY_LENGTH) If @error Then Return SetError(1, 0, "") $tUlong = _WinAPI_CopyStruct($tByteBuffer, "ulong value") ;If this is a block cipher (not a stream cipher) If $sAlgorithmId <> $CNG_BCRYPT_RC4_ALGORITHM Then ;Get length of block $tByteBuffer = __CryptoNG_BCryptGetProperty($hEncryptionKey, $CNG_BCRYPT_BLOCK_LENGTH) If @error Then Return SetError(1, 0, "") $tUlong = _WinAPI_CopyStruct($tByteBuffer, "ulong value") $iBlockLength = $tUlong.value _DebugOut("$iBlockLength = " & $iBlockLength) ;Create initialization vector (IV) buffer and set its default value (0x000102...) $xIV = Binary("") For $i = 0 To $iBlockLength - 1 $xIV &= Binary(Chr($i)) Next $tIVBuffer = DllStructCreate(StringFormat("byte data[%i]", $iBlockLength)) $tIVBuffer.data = $xIV _DebugOut("IV = " & $tIVBuffer.data) EndIf The specific line 3422, the DllStructCreate is creating a new DllStruct variable $tIVBuffer: $tIVBuffer = DllStructCreate(StringFormat("byte data[%i]", $iBlockLength)) A DllStruct variable $tByteBuffer is returned from __CryptoNG_BCryptGetProperty: $tByteBuffer = __CryptoNG_BCryptGetProperty($hEncryptionKey, $CNG_BCRYPT_BLOCK_LENGTH) A copy of that struct a created as $tUlong. I'm not entirely sure why _WinAPI_CopyStruct is used here. Does this function turn the DllStruct into a WinAPI struct format? I think CopyStruct is just a WinAPI call to copy the stuct at the memory location specified by $tByteBuffer. But isn't $tByteBuffer a DllStruct variable? $tUlong = _WinAPI_CopyStruct($tByteBuffer, "ulong value") Then $iBlockLength uses the ulong value of $tUlong. $iBlockLength = $tUlong.value It appears that DllStructCreate for $tIVBuffer uses $iBlockLength as a length for data[?]. $tIVBuffer = DllStructCreate(StringFormat("byte data[%i]", $iBlockLength)) $tIVBuffer.data = $xIV Also I see this reference in __CryptoNG_BCryptGetProperty on line 4880: _DebugOut("$tBuffer = " & $tBuffer.data) There is a .data property used for the DllStruct variable. What is contained in .data? The actual binary data of the struct in memory? Is there a list of other properties that can be accessed from a DllStruct directly? Generally, is my understanding of both examples above correct? I'm trying to understand what's going on, rather than mimicking the code. Again thanks for the help. I'm still studying both UDF's. They are so well organized and written. I especially like how the HTTPAPI API organizes the structs in a global header section. ;======================== ; STRUCTURES ;======================== ;Global HHTP Version Structure Global $__HTTPAPI_gtagHTTP_VERSION = _ "struct;" & _ "ushort MajorVersion;" & _ "ushort MinorVersion;" & _ "endstruct;" ;Global HHTPAPI Version Structure and Constants Global $__HTTPAPI_gtagHTTPAPI_VERSION = _ "struct;" & _ "ushort HttpApiMajorVersion;" & _ "ushort HttpApiMinorVersion;" & _ "endstruct;" And structs within structs: Global $__HTTPAPI_gtagHTTP_DATA_CHUNK_FROM_FRAGMENT_CACHE_EX = _ $__HTTPAPI_gtagHTTP_DATA_CHUNK & _ "struct;" & _ "ushort FragmentNameLength;" & _ ;in bytes not including the NUL "ptr pFragmentName;" & _ ;wstr "endstruct;" Also, I saw the data alignment techniques here: Global $__HTTPAPI_gtagHTTP_DATA_CHUNK = _ "struct;" & _ "int DataChunkType;" & _ "endstruct;" & _ (@AutoItX64 ? "" : "ptr;") ;Union alignment issue found & fixed by Danyfirex
-
TheXman reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
I tried to look at how different languages have implemented ZMQ bindings, and also did a search through Github for more information at the ZMQ repository. I saw references at https://travlr.github.io/libzmq/structzmq__msg__t.html that show: typedef struct {unsigned char _ [32];} zmq_msg_t; I've seen some people use this instead for 64-bit and similarly for 32-bit: type zmq_msg_t = ubyte unsigned char 8 __(0 to 63) as ubyte They all "seem" to work for those language binding implementations. In the msg.cpp, on line 44, there is code that shows: // Check whether the sizes of public representation of the message (zmq_msg_t) // and private representation of the message (zmq::msg_t) match. typedef char zmq_msg_size_check[2 * ((sizeof (zmq::msg_t) == sizeof (zmq_msg_t)) != 0) - 1]; bool zmq::msg_t::check () const { return _u.base.type >= type_min && _u.base.type <= type_max; } Reference: https://github.com/zeromq/libzmq/blob/master/src/msg.cpp#L44 The msg.hpp, https://github.com/zeromq/libzmq/blob/2ac9755ee9df54e453958136bd17fee5819dbdba/include/zmq.h#L229 has the definition that you refer to: /******************************************************************************/ /* 0MQ message definition. */ /******************************************************************************/ /* Some architectures, like sparc64 and some variants of aarch64, enforce pointer * alignment and raise sigbus on violations. Make sure applications allocate * zmq_msg_t on addresses aligned on a pointer-size boundary to avoid this issue. */ typedef struct zmq_msg_t { #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) __declspec(align (8)) unsigned char _[64]; #elif defined(_MSC_VER) \ && (defined(_M_IX86) || defined(_M_ARM_ARMV7VE) || defined(_M_ARM)) __declspec(align (4)) unsigned char _[64]; #elif defined(__GNUC__) || defined(__INTEL_COMPILER) \ || (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \ || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) unsigned char _[64] __attribute__ ((aligned (sizeof (void *)))); #else unsigned char _[64]; #endif } zmq_msg_t; That's the definition of zmq_msg_t within the ZMQ code for the DLL. That's what I'm experiencing running the functions. They do run and no errors generated, but there are unexpected issues. That's probably because of the memory alignment you refer to. @TheXman Thanks again for the suggestions and you're absolutely right. It really helps me muddle through learn how to implement this.
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
swoop reacted to a post in a topic: Working with DllCall and DllStruct on a ZeroMQ UDF (Questions)
-
@Nine Much appreciation for the help. Can't thank you enough for the guidance. Doing that allows the zmq_msg_init_data and the callback function to register and run without error. I now need to track down why the zmq_free_fn doesn't seem to clean up or free that memory. Does "ptr;ptr" for DllCallbackRegister params mean that for AutoIt functions being called back, one doesn't need to use the parameter names of the function? Global $hHandle = DllCallbackRegister(zmq_free_fn, "none", "ptr;ptr") Again, thanks for the help as I'm still a beginner with AutoIt.
-
Added some error messages, and there is an error code = 2 for the DllCallbackRegister shown as "ERROR: Registering ZMQ_FREE_F Error - @error = 2" Message Ptr = 0x000001D72E9D0FC0 Message Size = 32 Success: DllStructCreate($tag_data) Success: DllStructSetData($data... Data Ptr = 0x000001D72E9CB350 Data Size = 6 FuncName = ZMQ_FREE_FN ERROR: Registering ZMQ_FREE_F Error - @error = 2 zmq_msg_init_data = 0 Success: zmq_msg_init_data(... Closing Message = 0 Success: zmq_msg_close($msg) Success: DllCallbackFree($hHandle) !>07:32:56 AutoIt3.exe ended.rc:-1073740940 +>07:32:56 AutoIt3Wrapper Finished. >Exit code: 3221226356 Time: 2.114 I didn't find any error code references in the help file. If it is the same as the DllCall error code, then does that mean the "unknown error?" Here's the code: #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <constants.au3> Const $tag_zmq_msg_t = "BYTE var1[32];" Const $tag_zmq_msg_t64 = "BYTE var1[64];" ConsoleWrite(@CRLF & @CRLF & @CRLF) Global $msg = DllStructCreate($tag_zmq_msg_t) ; Show Message Pointer/Size ConsoleWrite(StringFormat("Message Ptr = %s", DllStructGetPtr($msg)) & @CRLF) ConsoleWrite(StringFormat("Message Size = %s", DllStructGetSize($msg)) & @CRLF) ; Create and Set Data Const $tag_data = "BYTE var1[6];" Global $data = DllStructCreate($tag_data) console_error (@error, "DllStructCreate($tag_data)") DllStructSetData($data, 1, "ABCDEF") console_error (@error, "DllStructSetData($data...") ; Show Data Size ConsoleWrite(StringFormat("Data Ptr = %s", DllStructGetPtr($data)) & @CRLF) ConsoleWrite(StringFormat("Data Size = %s", DllStructGetSize($data)) & @CRLF) ; Check to see what's the function's name ConsoleWrite("FuncName = " & FuncName(zmq_free_fn) & @CRLF) ; Create callback function. Global $hHandle = DllCallbackRegister("ZMQ_FREE_FN", "none", "pData;ptr;pHint;ptr") console_error (@error, "Registering ZMQ_FREE_F") ; Init message data ConsoleWrite(StringFormat("zmq_msg_init_data = %s", zmq_msg_init_data(DllStructGetPtr($msg),DllStructGetPtr($data),6,$hHandle,null)) & @CRLF) console_error (@error, "zmq_msg_init_data(...") ; Msg Close ConsoleWrite(StringFormat("Closing Message = %s", zmq_msg_close($msg)) & @CRLF) console_error (@error, "zmq_msg_close($msg)") ; Delete callback function. DllCallbackFree($hHandle) console_error (@error, "DllCallbackFree($hHandle)") ; Functions Func zmq_free_fn($pData, $pHint) ;Func zmq_free_fn(ByRef $pData, ByRef $pHint) $pData = 0 ; free $pData memory $pHint = 0 ; free $pHint memory EndFunc Func zmq_msg_init_data($pMsg,$pData,$iSize,$hHandle,$pHint) ; zmq_msg_init_data - initialise ØMQ message from a supplied buffer ; typedef void (zmq_free_fn) (void *data, void *hint); ; int zmq_msg_init_data (zmq_msg_t *msg, void *data, size_t size, zmq_free_fn *ffn, void *hint); ; http://api.zeromq.org/master:zmq-msg-init-data Local $aDllCallReturn = DllCall("libzmq-v142-mt-4_3_4.dll","int","zmq_msg_init_data","struct*",$pMsg,"ptr",$pData,"uint",$iSize,"ptr",DllCallbackGetPtr($hHandle),"ptr",$pHint) Return $aDllCallReturn[0] EndFunc Func zmq_msg_close($pMsg) ; zmq_msg_close - release ØMQ message : int zmq_msg_close (zmq_msg_t *msg); ; http://api.zeromq.org/master:zmq-msg-close Local $aDllCallReturn = DllCall("libzmq-v142-mt-4_3_4.dll","int","zmq_msg_close","struct*",$pMsg) Return $aDllCallReturn[0] EndFunc Func console_error ($errno, $tag) If $errno Then ConsoleWrite("ERROR: " & $tag & " Error - @error = " & $errno & @CRLF) Else ConsoleWrite("Success: " & $tag & @CRLF) EndIf EndFunc If I use the following for the zmq_free_fn function with ByRef instead: Func zmq_free_fn(ByRef $pData, ByRef $pHint) $pData = 0 ; free data from memory $pHint = 0 ; free hint from memory EndFunc Message Ptr = 0x000001B81A7CC220 Message Size = 32 Success: DllStructCreate($tag_data) Success: DllStructSetData($data... Data Ptr = 0x000001B81A7CBCC0 Data Size = 6 FuncName = ZMQ_FREE_FN ERROR: Registering ZMQ_FREE_F Error - @error = 3 !>07:31:46 AutoIt3.exe ended.rc:-1073740940 +>07:31:46 AutoIt3Wrapper Finished. >Exit code: 3221226356 Time: 2.261 I get an error 3 (I don't know, Function not found?) from the DllCallbackRegister function, and the rest of the script doesn't execute. Should the data type for the call back parameters be written as: ; Create callback function. Global $hHandle = DllCallbackRegister("zmq_free_fn", "none", "pData;ptr;pHint;ptr") or should it be: ; Create callback function. Global $hHandle = DllCallbackRegister("zmq_free_fn", "none", "pData;none;pHint;none")
-
@TheXman I tried to get further with the ZeroMQ initialization functions. The zmq_msg_init and zmq_msg_close appear to run fine, returning 0. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** Const $tag_zmq_msg_t = "BYTE var1[32];" Const $tag_zmq_msg_t64 = "BYTE var1[64];" Func zmq_msg_init($pMsg) ; zmq_msg_init - initialise empty ØMQ message : int zmq_msg_init (zmq_msg_t *msg); ; http://api.zeromq.org/master:zmq-msg-init Local $aDllCallReturn = DllCall("libzmq-v142-mt-4_3_4.dll","int","zmq_msg_init","struct*",$pMsg) Return $aDllCallReturn[0] EndFunc Func zmq_msg_close($pMsg) ; zmq_msg_close - release ØMQ message : int zmq_msg_close (zmq_msg_t *msg); ; http://api.zeromq.org/master:zmq-msg-close Local $aDllCallReturn = DllCall("libzmq-v142-mt-4_3_4.dll","int","zmq_msg_close","struct*",$pMsg) Return $aDllCallReturn[0] EndFunc ConsoleWrite(@CRLF & @CRLF & @CRLF) Global $msg = DllStructCreate($tag_zmq_msg_t) ; Test Simple Msg Init and Close ConsoleWrite(StringFormat("Init Message Result = %s", zmq_msg_init($msg)) & @CRLF) ConsoleWrite(StringFormat("Closing Message Result = %s", zmq_msg_close($msg)) & @CRLF) Although I am getting the zmq_msg_init_data to run, it sometimes does not get to the end of the script and terminate. Am I missing something simple? #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** Const $tag_zmq_msg_t = "BYTE var1[32];" Const $tag_zmq_msg_t64 = "BYTE var1[64];" Func zmq_free_fn(ByRef $pData, ByRef $pHint) $pData = 0 $pHint = 0 EndFunc Func zmq_msg_init_data($pMsg,$pData,$iSize,$hHandle,$pHint) ; zmq_msg_init_data - initialise ØMQ message from a supplied buffer ; typedef void (zmq_free_fn) (void *data, void *hint); ; int zmq_msg_init_data (zmq_msg_t *msg, void *data, size_t size, zmq_free_fn *ffn, void *hint); ; http://api.zeromq.org/master:zmq-msg-init-data Local $aDllCallReturn = DllCall("libzmq-v142-mt-4_3_4.dll","int","zmq_msg_init_data","struct*",$pMsg,"ptr",$pData,"uint",$iSize,"ptr",DllCallbackGetPtr($hHandle),"ptr",$pHint) Return $aDllCallReturn[0] EndFunc Func zmq_msg_close($pMsg) ; zmq_msg_close - release ØMQ message : int zmq_msg_close (zmq_msg_t *msg); ; http://api.zeromq.org/master:zmq-msg-close Local $aDllCallReturn = DllCall("libzmq-v142-mt-4_3_4.dll","int","zmq_msg_close","struct*",$pMsg) Return $aDllCallReturn[0] EndFunc ConsoleWrite(@CRLF & @CRLF & @CRLF) Global $msg = DllStructCreate($tag_zmq_msg_t) ; Show Message Pointer/Size ConsoleWrite(StringFormat("Message Ptr = %s", DllStructGetPtr($msg)) & @CRLF) ConsoleWrite(StringFormat("Message Size = %s", DllStructGetSize($msg)) & @CRLF) ; Create and Set Data Const $tag_data = "BYTE var1[6];" Global $data = DllStructCreate($tag_data) DllStructSetData($data, 1, "ABCDEF") ; Show Data Size ConsoleWrite(StringFormat("Data Ptr = %s", DllStructGetPtr($data)) & @CRLF) ConsoleWrite(StringFormat("Data Size = %s", DllStructGetSize($data)) & @CRLF) ; Create callback function. Global $hHandle = DllCallbackRegister("zmq_free_fn", "none", "pData;pHint") ; Init message data ConsoleWrite(StringFormat("zmq_msg_init_data = %s", zmq_msg_init_data(DllStructGetPtr($msg),DllStructGetPtr($data),6,$hHandle,null)) & @CRLF) ; Msg Close ConsoleWrite(StringFormat("Closing Message = %s", zmq_msg_close($msg)) & @CRLF) ; Delete callback function. DllCallbackFree($hHandle) I'm trying to mimic the C++ example given by the documentation: http://api.zeromq.org/master:zmq-msg-init-data void my_free (void *data, void *hint) { free (data); } /* ... */ void *data = malloc (6); assert (data); memcpy (data, "ABCDEF", 6); zmq_msg_t msg; rc = zmq_msg_init_data (&msg, data, 6, my_free, NULL); assert (rc == 0);
-
@Nine You're right, I didn't check the line split. My bad. You're also right about the error checking. I tried to check if the zeromq dll call is not working for a simpler function using the DllCall generator to get the ZMQ version information, and I get back: "DllCall error (libzmq.dll/zmq_version): Unable to use the DLL file. Possibly a problem with the parameters." $aDllCallReturn = DllCall("libzmq-v142-mt-4_3_4.dll","ptr","zmq_version","LONG_PTR","$major","LONG_PTR","$minor","LONG_PTR","$patch") If @error Then Switch @error Case 1 MsgBox(0,"DllCall Code Generator","DllCall error (libzmq.dll/zmq_version): Unable to use the DLL file. Possibly a problem with the parameters.") Case 2 MsgBox(0,"DllCall Code Generator","DllCall error (libzmq.dll/zmq_version): Unknown return type.") Case 3 MsgBox(0,"DllCall Code Generator","DllCall error (libzmq.dll/zmq_version): Function not found in DLL file. Remember that function names are case sensitive.") Case 4 MsgBox(0,"DllCall Code Generator","DllCall error (libzmq.dll/zmq_version): Incorrect number of parameters.") Case 5 MsgBox(0,"DllCall Code Generator","DllCall error (libzmq.dll/zmq_version): Bad parameter.") Case Else MsgBox(0,"DllCall Code Generator","DllCall error (libzmq.dll/zmq_version): Unknown/unspecified error.") EndSwitch $vDllCallReturn = "" Else $vDllCallReturn = $aDllCallReturn[0] $major = $aDllCallReturn[1] $minor = $aDllCallReturn[2] $patch = $aDllCallReturn[3] MsgBox(0,"DllCall Code Generator","$major = " & $major & @CRLF & "$minor = " & $minor & @CRLF & "$patch = " & $patch & @CRLF & "DllCall return value: " & $vDllCallReturn) EndIf http://api.zeromq.org/master:zmq-version void zmq_version (int *major, int *minor, int *patch); @TheXman Thank you for the correction.
-
I'm not sure if my knowledge of AutoIt DllStruct and the C++ typedef is correct. Is the following: typedef struct {unsigned char _ [32];} zmq_msg_t; equivalent to: Global Const $tag_zmq_msg_t = "struct;BYTE var1" When I run the AutoIt snippet, I get the following attached error. Error parsing function call. The DLL can be found here in the latest release from ZeroMQ: https://github.com/zeromq/libzmq/releases
-
I am working on a ZeroMQ UDF and have gotten most of the AutoIt wrapper functions and constants finished. But I am encountering some difficulties with a few of the ZMQ exported functions and would kindly ask if anyone can guide me on the best way to accomplish it in AutoIt. 1) Am I creating the right struct for zmq_msg_t ? 2) Is my zmq_free_fn usage in AutoIt similar to the my_free function in the ZMQ C++ example? The usage of the exported ZMQ function zmq_msg_init_data in C++ is this: typedef void (zmq_free_fn) (void *data, void *hint); typedef struct {unsigned char _ [32];} zmq_msg_t; void ffn (void *data_, void *hint_) { // Signal that ffn has been called by writing "freed" to hint (void) data_; // Suppress 'unused' warnings at compile time memcpy (hint_, (void *) "freed", 5); } void my_free (void *data, void *hint) { free (data); } /* ... */ void *data = malloc (6); assert (data); memcpy (data, "ABCDEF", 6); zmq_msg_t msg; rc = zmq_msg_init_data (&msg, data, 6, my_free, NULL); assert (rc == 0); My AutoIt wrapper function for the DllCall is currently this: Global Const $tag_zmq_msg_t = "struct;BYTE var1" Global $tzmq_msg_t = DllStructCreate($tag_zmq_msg_t) ; this step would actually use zmq_msg_init Func zmq_msg_init_data($pMsg,$pData,$iSize,$pHint) Local $aDllCallReturn = DllCall("libzmq.dll","LONG","zmq_msg_init_data","STRUCT*",$pMsg,"PTR",$pData, "UINT",$iSize,"PTR",zmq_free_fn($pData,$pHint),"PTR",$pHint) Return $aDllCallReturn[0] EndFunc Func zmq_free_fn($pData=0,$pHint=0) $pData = 0 EndFunc Local $tzmq_msg = DllStructSetData($tzmq_msg_t, 1, "ABCDEF") Local $tzmq_data = DllStructGetPtr($tzmq_msg) Local $rc = zmq_msg_init_data($tzmq_msg,$tzmq_data,6,null) The export of the C++ function call looks like this for zmq_msq_init_data: int zmq_msg_init_data (zmq_msg_t *msg, void *data, size_t size, zmq_free_fn *ffn, void *hint); And a description for the zmq_msg_init_data function is here: http://api.zeromq.org/master:zmq-msg-init-data Also, there is some code in the ZeroMQ library that handles different OS arch during compilation of the libzmq.dll for the struct memory alignment: typedef struct zmq_msg_t { #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) __declspec(align (8)) unsigned char _[64]; #elif defined(_MSC_VER) \ && (defined(_M_IX86) || defined(_M_ARM_ARMV7VE) || defined(_M_ARM)) __declspec(align (4)) unsigned char _[64]; #elif defined(__GNUC__) || defined(__INTEL_COMPILER) \ || (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \ || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) unsigned char _[64] __attribute__ ((aligned (sizeof (void *)))); #else unsigned char _[64]; #endif } zmq_msg_t; References: http://api.zeromq.org/master:zmq-msg-init-data https://travlr.github.io/libzmq/structzmq__msg__t.html https://github.com/zeromq/libzmq/blob/2ac9755ee9df54e453958136bd17fee5819dbdba/include/zmq.h#L236 https://github.com/zeromq/libzmq/blob/3070a4b2461ec64129062907d915ed665d2ac126/src/msg.hpp#L46 https://github.com/zeromq/libzmq/blob/3070a4b2461ec64129062907d915ed665d2ac126/src/msg.hpp#L45 https://github.com/zeromq/libzmq/blob/3070a4b2461ec64129062907d915ed665d2ac126/src/zmq.cpp#L624
-
Does anyone know how to access AutoIt from Golang using trancexx's Access AutoIt method? I saw some COM helpers in a Go-OLE/COM library at: https://github.com/go-ole/com/blob/fd770a131a7ed4c177a3f011a989ed3647331887/com/com.go func BindMoniker(moniker uintptr, option int32, interfaceID *GUID, object interface{}) error { return api.BindMoniker(moniker, option, interfaceID, object) } And also this one: // CoGetClassObject in Windows API. func CoGetClassObject() { return api.CoGetClassObject() } In a language like Python, it seems simple with just: oAutoIt = win32com.client.GetObject("AutoIt.Application") oAutoIt.Call("Sleep", 3000) Or in C#: dynamic myAu3Object = Marshal.BindToMoniker("AutoIt.Application"); myAu3Object.Call("Sleep", 1000); Any help would be greatly appreciated.
-
Prevent Process from Starting in Windows
swoop replied to swoop's topic in AutoIt General Help and Support
Thanks for the the advice. If using processclose on an infinite loop, that loop would need to run a few times every second to prevent the update program from triggering. I noticed once it triggers, it instantly triggers the other program processes to then go into a shutdown. Thus, is there an easy way to trap the process from running in a similar way that an anti-virus program would? I wish I could disable auto-update, but the company in their need to keep everyone up-to-date, now forces an auto-update policy. It's because for years, and even for more than a decade, users won't update because each new update produces double the critical bugs than fixes. Especially when they are adding lots of new functionality, without fixing the core bugs that matter most. So there are many users that refuse to upgrade, and the company is now forcing end-of-life to many old versions, too. I guess when Microsoft decided to force updates on Windows 10 users and got away with doing it, this company also decided to do it as well. I and many other users wouldn't be as steamed about it, but the company decides when to auto-update when they deem it convenient-- which is randomly, during the most critical times of the day.