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 :wink:
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 8)