Page 1 of 1
How to know the DIM of a array?
Posted: Thu Nov 02, 2006 4:47 pm
by jqn
Hi,
I've received in my program an array dimensioned in another program or process. (its memory address, of course)
It's possible to know how many elements are dimensioned in the array?.
many thanks.
JOAQUIN
Posted: Thu Nov 02, 2006 5:14 pm
by Flype
if it is an external program / process you can't do that.
that's why the bytes length of the array is always provided in such case.
but if it's an external PureBasic program it might work with this tricks (not future-proof).
Code: Select all
Macro CountArray(array)
PeekL(@array-8)
EndMacro
Structure TEST
a.s
b.s
c.l
EndStructure
Dim table.TEST(10)
Debug CountArray(table())
Redim table.TEST(100)
Debug CountArray(table())
Posted: Thu Nov 02, 2006 5:44 pm
by jqn
Thanks, Flype.
Unfortunately, my program source is mySQL.
It returns a *row pointer to an C-array (1 based).
I've tried your trick, but it seems that it dont work.
Posted: Thu Nov 02, 2006 6:02 pm
by Flype
mySQL ?
ok, but it's not a problem...
i've done many tries with mySQL, parsing rows, etc...
i will post an example.
Posted: Thu Nov 02, 2006 6:08 pm
by Flype
normally you have to do it this way :
Code: Select all
For i = 0 To mysql_num_rows(result) - 1
*row.MYSQL_ROW = mysql_fetch_row(result)
If *row
Rows.s = ""
For j = 0 To mysql_num_fields(result) - 1
Rows + *row\field[j] + ", "
Next
Debug "rows>"+Rows
EndIf
Next
you can have a longer look at this piece of code here :
http://www.penguinbyte.com/apps/pbwebst ... mysql5.zip
Posted: Fri Nov 03, 2006 9:01 am
by jqn
I know mysql_num_fields(), and I use it.
But I need to use the fields array in a DLL who can't connect to DB.
Of course, I can send num_fields as a parameter to DLL, but I would to avoid it because the DLL is used in a lot of processes.
If there is no another solution….
Posted: Fri Nov 03, 2006 9:07 am
by Flype
you might also parse the array of fields UNTIL you have a NULL value.
it could work - not tested.
Posted: Fri Nov 03, 2006 9:21 am
by jqn
I've tried it.
It produces a windows system error when it reach the end (out of memory, I suppose). I dont have a chance for testing the end+1 element.
Posted: Fri Nov 03, 2006 10:47 am
by Flype
i tried something but it's not perfect...
it can parse for rows and fields without any count-like function.
Code: Select all
Structure MEM_ROOT
*free
*used
*pre_alloc
min_malloc.l
block_size.l
block_num.l
first_block_usage.l
*error_handler
*dummy ; ????
EndStructure
Structure MYSQL
;
EndStructure
Structure MYSQL_ROW
field.s[0]
EndStructure
Structure MYSQL_RES
row_count.l
*fields.MYSQL_FIELD
*data.MYSQL_DATA
*data_cursor.MYSQL_ROWS
*lengths
*handle.MYSQL
field_alloc.MEM_ROOT
field_count.l
current_field.l
row.MYSQL_ROW
current_row.MYSQL_ROW
_eof.l
EndStructure
Structure MYSQL_DATA
;
EndStructure
Import "libmysql.lib" ; mysql
mysql_init.l(*mysql.MYSQL)
mysql_real_connect.l(*mysql.MYSQL,host.s,user.s,passwd.s,db.s,port.l,unix_socket.s,client_flag.l)
mysql_query.l(*mysql.MYSQL,query.s)
mysql_store_result.l(*mysql.MYSQL)
mysql_fetch_row.l(*result.MYSQL_RES)
mysql_free_result.l(*result.MYSQL_RES)
mysql_close.l(*mysql.MYSQL)
EndImport
hDB = mysql_init(#Null)
If hDB
If mysql_real_connect(hDB, "localhost", "root", "", "", 3306, "NULL", #Null)
If mysql_query(hDB, "SELECT host, user, password, '', 'test' FROM mysql.user;") = #NO_ERROR
*res.MYSQL_RES = mysql_store_result(hDB)
If *res
For i = 0 To *res\row_count - 1
Debug "============================="
*row.MYSQL_ROW = mysql_fetch_row(*res)
If *row
For j = 0 To *res\field_count - 1
Debug *row\field[j]
Next
EndIf
Next
mysql_free_result(*res)
EndIf
EndIf
EndIf
mysql_close(hDB)
EndIf
Posted: Fri Nov 03, 2006 11:51 am
by Flype
[EDIT] see previous post.
Posted: Fri Nov 03, 2006 12:32 pm
by jqn
it can parse for rows and fields without any count-like function.
You're using "field_count.l", a subfield from MYSQL_RES structure. My problem with it is similar to use "mysql_num_fields()" when I query to DB in a previous program: I need to send it to DLL.
In the DLL I've only the *row pointer.
I'm looking for a function (if exists) like it from your first post:
Macro CountArray(array)
PeekL( @array- 8 )
EndMacro
Many thanks for your interest in this question.
JOAQUIN
Posted: Fri Nov 03, 2006 1:20 pm
by Flype
so, i'm out of solution
you must transmit either the *result pointer or the row count

i don't think that transmitting the row count is cpu/time critical.
Posted: Fri Nov 03, 2006 1:49 pm
by jqn
I think I've solved.
Use this code after your "mysql_fetch_row()" statement:
Code: Select all
nf = 0
ini = peekl(*row)
debug str(ini)
lon=0
Repeat
new.l=peekl(*row+(nf*4))
if new = ini+lon
debug str(nf)+" : "+ *row\field[nf]
lon + len(*row\field[nf]) + 1
nf + 1
else
break
endif
forever
It checks if next address on *row memory is pointed to a new field.
Despite, mysql adds a "trailer" field without data. So, the last field must be
ignored.
JOAQUIN
Posted: Fri Nov 03, 2006 2:02 pm
by Flype
well done
