/******************************************************/ //Author: Rajesh Ramachandran //Found in: http://community.flexerasoftware.com/showthread.php?t=60963 // //Arrays in InstallScript are not laid out like C/C++ arrays. InstallScript //arrays are actually OleAutomation SAFEARRAYs. Hence to pass //these arrays to .dll functions that expect a C style array requires some //work(magic!). Look at the script below to see how that's done: // /******************************************************/ #include "ifx.h" /*Dumps an array into a string. Elements are separated by a space*/ prototype STRING StreamArray(VARIANT); function STRING StreamArray(array) NUMBER i; STRING s; begin for i = 0 to SizeOf(array) - 1 s = s + array(i) + " "; endfor; return s; end; /*Mirroring the C/C++ SAFEARRAY data structure*/ typedef _SAFEARRAY begin SHORT cDims; SHORT fFeatures; LONG cbElements; LONG cLocks; POINTER pvData; /*rgsaBound omitted*/ end; /*Mirroring the C/C++ VARIANT data structure*/ typedef _VARIANT begin SHORT vt; SHORT wReserved1; SHORT wReserved2; SHORT wReserved3; NUMBER theRealData; // The exact type of this member depends on vt end; prototype POINTER Array2Pointer(BYREF VARIANT); function POINTER Array2Pointer(array) _VARIANT POINTER pVariant; _SAFEARRAY POINTER pArray; begin pVariant = &array; pArray = pVariant->theRealData; return pArray->pvData; end; prototype BOOL PSAPI.EnumProcesses(POINTER, LONG, BYREF LONG); function OnBegin() LONG processIDs(512); LONG cb, cbNeeded; begin cb = SizeOf(processIDs) * 4; // 4 = SizeOf DWORD EnumProcesses(Array2Pointer(processIDs), cb, cbNeeded); /*Shrink the Array to the no. of items returned by EnumProcesses This is needed to prevent StreamArray from outputting junk*/ Resize(processIDs, cbNeeded / 4); MessageBox(StreamArray(processIDs), INFORMATION); abort; end; /*******************************************************************/ // //The Array2Pointer function is the key here. When you declare an array variable //what internally gets created is a VARIANT variable which holds the SAFEARRAY. //Hence the Array2Pointer function *typecasts* the pointer to the array to a _VARIANT //pointer to extract the SAFEARRAY pointer from it. The pointer to the actual data //is extracted from the _SAFEARRAY pointer. _VARIANT & _SAFEARRAY are //InstallScript typedefs which mirror the layout of their C/C++ counterparts.