JRowe Posted October 10, 2009 Share Posted October 10, 2009 (edited) To get an array from a dllcall, you need to create the array first from dllStructCreate, like so $myArray = dllStructCreate("int[10]") Then pass the array struct by pointer in the dllCall $dllCall = DLLCall($dll, "return type", "_some_function_name", "array type", DLLStructGetPtr($myArray)) Now the array is filled with whatever DLLCall returned, giving you the opportunity to get the values of the array by using DLLStructGetData. I'm running a For/Next loop, filling in the values of an AutoIt array. I'm getting the datatypes straight from the source of the DLL I'm using, and everything is working with no errors. I just want to make sure that this isn't going to blow up someone'scomputer when I release a UDF, lol. I also wanted to write it out tomake it more concrete in my own mind. Is this the correct way to interact with arrays when using DLLCall? Thanks for your time. Edited October 10, 2009 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
trancexx Posted October 10, 2009 Share Posted October 10, 2009 I'm confused with some parts of what you are saying. Thing is that if you are passing a pointer to a structure then you use "ptr" as type of that parameter. So, in your case "array type" would always be "ptr". But likely I misunderstood what you mean. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
JRowe Posted October 10, 2009 Author Share Posted October 10, 2009 (edited) What I'm doing is interacting with an array that the dll/c code generates. The dll function creates an array, and I access it by creating a DllStruct with the appropriate parameters and then using DLLStructGetData and DLLStructSetData to access the elements of the array. I've successfully interacted with a 3 dimensional array created by a DLLCall. Specifically, the function I wrote returns a 3 dimensional array generated by a dll: Func _ANNGetConnectionArray($dll, ByRef $hAnn) $numConnections = _ANNGetTotalConnections($dll, $hAnn) $ConnectionArrayStruct = DllStructCreate("int[" & $numConnections & "];" & "int[" & $numConnections & "];" & "int[" & $numConnections & "]") $dllCall = DllCall($dll, "none", "_fann_get_connection_array@8", "hwnd", $hAnn, "int", DllStructGetPtr($ConnectionArrayStruct)) Local $ConnectionArray[$numConnections][3] For $i = 1 to $numConnections Step 1 $ConnectionArray[$i-1][0] = DllStructGetData($ConnectionArrayStruct, 1, $i) $ConnectionArray[$i-1][1] = DllStructGetData($ConnectionArrayStruct, 2, $i) $ConnectionArray[$i-1][2] = DllStructGetData($ConnectionArrayStruct, 3, $i) Next Return $ConnectionArray EndFunc Took me awhile to get there, but @error is showing clean, the function is returning the expected data, and there's no crashing going on, so I'm gonna assume all is well. These last few weeks have been very enlightening for me, I'm finally grasping some major concepts. The next fun thing is inverting the function I just posted, to create a 3D array from an AutoIt array and pass it to the dll as a parameter. Once I get past this stage, I think I'm going to start being a helluva lot more productive in my contributions to the community. Thanks, trancexx, I appreciate the input! Edited October 10, 2009 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
trancexx Posted October 10, 2009 Share Posted October 10, 2009 That's ok, just change "int", DllStructGetPtr to "ptr", DllStructGetPtr.It's more correct. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
JRowe Posted October 10, 2009 Author Share Posted October 10, 2009 Excellent, I got lucky that int can double as ptr. (stupid pun intended) [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
JRowe Posted October 11, 2009 Author Share Posted October 11, 2009 (edited) And, I'm back for more.I have a problem, I'm not sure how to go about this. How do I recreate this struct using DLLStructCreate?struct fann_train_data { enum fann_errno_enum errno_f; FILE *error_log; char *errstr; unsigned int num_data; unsigned int num_input; unsigned int num_output; fann_type **input; fann_type **output; };The enum_fann_errno is just an int. Do I need to create the file struct and pass it to this struct by ptr?#ifndef _FILE_DEFINED struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE; #define _FILE_DEFINED #endifThe char *errstr I can deal with, it's just a pointer to an array of characters. The **input and **outputs I can generate as an array of pointers to arrays. The only thing I'm stuck on is how to deal with the FILE *error_logSorry, forgot my actual AutoIt code:;Initialize data struct to pass to _fann_train_on_data $dataStruct = DllStructCreate("int;ptr;ptr;int;int;int;ptr[" & $numSets & "];ptr[" & $numSets & "]") DllStructSetData($dataStruct, 1, 0) DllStructSetData($dataStruct, 2, 0) DllStructSetData($dataStruct, 3, 0) DllStructSetData($dataStruct, 4, $numSets) DllStructSetData($dataStruct, 5, $numInputs) DllStructSetData($dataStruct, 6, $numInputs)Since I can get everything to work by just passing a file to a different function, I might skip this and make some AutoIt based array/file functions that mimic it's functionality. Edited October 11, 2009 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
Authenticity Posted October 11, 2009 Share Posted October 11, 2009 I think that you can presume it's just a pointer to an object. Not exactly but quite like a pointer to a FONT or log font. What should be accurate is it's structure size + any padding necessary for alignment. Use sizeof() or calculate it yourself and round to the next 4 bytes multiplication. 12 -> 16, etc. Not sure though. Link to comment Share on other sites More sharing options...
JRowe Posted October 13, 2009 Author Share Posted October 13, 2009 (edited) Well, I'm at it again, I think I'm close, but this code is giving me fits. It hard crashes on the dllCall: expandcollapse popup$inputArrayStruct = DllStructCreate("ptr[4]") $inputArrayStruct1 = DllStructCreate("float[2]") $inputArrayStruct2 = DllStructCreate("float[2]") $inputArrayStruct3 = DllStructCreate("float[2]") $inputArrayStruct4 = DllStructCreate("float[2]") $outputArrayStruct = DllStructCreate("ptr[4]") $outputArrayStruct1 = DllStructCreate("float") $outputArrayStruct2 = DllStructCreate("float") $outputArrayStruct3 = DllStructCreate("float") $outputArrayStruct4 = DllStructCreate("float") DllStructSetData($inputArrayStruct1, 1, -1, 1) DllStructSetData($inputArrayStruct1, 1, -1, 2) DllStructSetData($inputArrayStruct2, 1, -1, 1) DllStructSetData($inputArrayStruct2, 1, 1, 2) DllStructSetData($inputArrayStruct3, 1, 1, 1) DllStructSetData($inputArrayStruct3, 1, -1, 2) DllStructSetData($inputArrayStruct4, 1, 1, 1) DllStructSetData($inputArrayStruct4, 1, 1, 2) DllStructSetData($outputArrayStruct1, 1, -1) DllStructSetData($outputArrayStruct2, 1, 1) DllStructSetData($outputArrayStruct3, 1, 1) DllStructSetData($outputArrayStruct4, 1, -1) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct1), 1) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct2), 2) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct3), 3) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct4), 4) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct1), 1) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct2), 2) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct3), 3) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct4), 4) _InitializeANN() $Ann = _CreateAnn($num_layers, $ANNLayers) _ANNSetActivationFunctionHidden($Ann, $FANN_SIGMOID_SYMMETRIC) _ANNSetActivationFunctionOutput($Ann, $FANN_SIGMOID_SYMMETRIC) $trainDataStruct = DllStructCreate("uint num_data;uint num_input;uint num_output;ptr inputs;ptr outputs") DllStructSetData($trainDataStruct, "num_data", 4) DllStructSetData($trainDataStruct, "num_input", 2) DllStructSetData($trainDataStruct, "num_output", 1) DllStructSetData($trainDataStruct, "inputs", DllStructGetPtr($inputArrayStruct)) DllStructSetData($trainDataStruct, "outputs", DllStructGetPtr($outputArrayStruct)) DllCall($hFannDll, "none", "_fann_train_on_data@20", "hwnd", $Ann, _ "ptr", DllStructGetPtr($trainDataStruct), _ "dword", $max_epochs, _ "dword", $epochs_between_reports, _ "float", $desired_error) The pieces are all here, but I can't seem to figure out how to put them together. Any help at all is greatly appreciated, if more is needed from me, please let me know. Context of what I'm trying to do: The function requires a "data" struct. The "data" struct is put together as shown above in the c code. I'm choking on **input and **output. I'm reading them as pointers to arrays of data, and attempting to build those arrays using dllStructSetData. I'm convinced I'm almost there, but I can't see how it falls together. Edited October 13, 2009 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
trancexx Posted October 13, 2009 Share Posted October 13, 2009 Underscore in DllStructCreate().Find better names. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
JRowe Posted October 13, 2009 Author Share Posted October 13, 2009 (edited) Fixed the naming issue, I think. Sorry about that.expandcollapse popup$inputArrayStruct = DllStructCreate("ptr[4]") $inputArrayStruct1 = DllStructCreate("float[2]") $inputArrayStruct2 = DllStructCreate("float[2]") $inputArrayStruct3 = DllStructCreate("float[2]") $inputArrayStruct4 = DllStructCreate("float[2]") $outputArrayStruct = DllStructCreate("ptr[4]") $outputArrayStruct1 = DllStructCreate("float") $outputArrayStruct2 = DllStructCreate("float") $outputArrayStruct3 = DllStructCreate("float") $outputArrayStruct4 = DllStructCreate("float") DllStructSetData($inputArrayStruct1, 1, -1, 1) DllStructSetData($inputArrayStruct1, 1, -1, 2) DllStructSetData($inputArrayStruct2, 1, -1, 1) DllStructSetData($inputArrayStruct2, 1, 1, 2) DllStructSetData($inputArrayStruct3, 1, 1, 1) DllStructSetData($inputArrayStruct3, 1, -1, 2) DllStructSetData($inputArrayStruct4, 1, 1, 1) DllStructSetData($inputArrayStruct4, 1, 1, 2) DllStructSetData($outputArrayStruct1, 1, -1) DllStructSetData($outputArrayStruct2, 1, 1) DllStructSetData($outputArrayStruct3, 1, 1) DllStructSetData($outputArrayStruct4, 1, -1) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct1), 1) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct2), 2) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct3), 3) DllStructSetData($inputArrayStruct, 1, DllStructGetPtr($inputArrayStruct4), 4) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct1), 1) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct2), 2) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct3), 3) DllStructSetData($outputArrayStruct, 1, DllStructGetPtr($outputArrayStruct4), 4) _InitializeANN() $Ann = _CreateAnn($num_layers, $ANNLayers) _ANNSetActivationFunctionHidden($Ann, $FANN_SIGMOID_SYMMETRIC) _ANNSetActivationFunctionOutput($Ann, $FANN_SIGMOID_SYMMETRIC) $trainDataStruct = DllStructCreate("uint numdata;uint numinput;uint numoutput;ptr inputs;ptr outputs") DllStructSetData($trainDataStruct, "numdata", 4) DllStructSetData($trainDataStruct, "numinput", 2) DllStructSetData($trainDataStruct, "numoutput", 1) DllStructSetData($trainDataStruct, "inputs", DllStructGetPtr($inputArrayStruct)) DllStructSetData($trainDataStruct, "outputs", DllStructGetPtr($outputArrayStruct)) DllCall($hFannDll, "none", "_fann_train_on_data@20", "hwnd", $Ann, _ "ptr", DllStructGetPtr($trainDataStruct), _ "dword", $max_epochs, _ "dword", $epochs_between_reports, _ "float", $desired_error)numdata = number of data setsnuminput = number of input values in each data setnumoutput = number of output values in each data set$inputStruct represents a 2d array of values, like so:inputStruct[0][0] = -1 inputStruct[0][1] = -1 inputStruct[1][0] = -1 inputStruct[1][1] = 1 inputStruct[2][0] = 1 inputStruct[2][1] = -1 inputStruct[3][0] = 1 inputStruct[3][1] = 1$outputStruct is a 1d array, like so:outputStruct[0] = -1 outputStruct[1] = 1 outputStruct[2] = 1 outputStruct[3] = -1I'm pretty sure that my major issue is coming from correctly presenting the input struct to dllCall, or "ptr inputs" in the DLLStructCreate. It should be a 2d array of floats. Edited October 13, 2009 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
JRowe Posted October 13, 2009 Author Share Posted October 13, 2009 omg, it's correct. After I cleaned up the underscores and added the correct struct parameters it worked. THANK YOU TRANCEXX! [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
trancexx Posted October 13, 2009 Share Posted October 13, 2009 I can't wait to see you posting in examples forum. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now