Passing const char* c->zbasic

Discussion of issues related specifically to writing code for native mode devices. This includes ZBasic code as well as assembly language code and C code, both inline and standalone.
Post Reply
ndudman
Posts: 79
Joined: 25 December 2008, 14:00 PM

Passing const char* c->zbasic

Post by ndudman »

Hi Iḿ trying to write the following sub... which is called from some c code and intended to pass a const char* into zbasic. Am I heading in the write direction ? Not sure if Ive got the if check for str termination correct or if the subroutine parameter declaration is ok. Im not able to test it yet to determine if it works, although Im sure I am missing something

Code: Select all

'~ To be called from the Menu_imp.c which needs to pass 
'~ a const char* to this zbasic subroutine
'~ The generated c function should have prototype (void)(const char*) 
public sub DisplayStr_C(byval strPtr as UnsignedInteger)
	Dim d() as Byte Based strPtr
	Dim str as String = ""
	Dim i as byte = 0
	do
		if (d(i) = 0) then
			exit do
		end if
		str = str & d(i)
		i = i + 1		
	loop
	call DisplayStr(str)
end sub
Thanks
Neil
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

There were a couple of minor problems in the proposed subroutine which I've fixed in the rendition below. The first is that the array d() is 1-based in ZBasic so the variable i must be initialized to 1. The second problem is that you must use the Chr() function when you append the characters to the string.

Code: Select all

Public Sub DisplayStr_C(ByVal strAddr as UnsignedInteger)
   Dim d() as Byte Based strAddr
   Dim str as String = ""
   Dim i as byte = 1
   Do
      If (d(i) = 0) Then
         Exit Do
      End If
      str = str & Chr(d(i))
      i = i + 1      
   Loop
   Call DisplayStr(str)
End Sub
As for the const char * formal parameter needed by your C calling routine, it wouldn't make sense for ZBasic to generate code with a const char * parameter corresponding to a ZBasic integral value. If we did, then code that needed to modify the memory at that address wouldn't work.

The solution is to introduce an intermediary function in your C code that takes a const char * parameter and casts it to an integral value to match the ZBasic subroutine parameter. The example code below may work for that purpose. Depending on how it is used in the C code you may be able to replace it with a #define.

Code: Select all

void
intermediary(const char *str)
{
  zf_DisplayStr_C((uint16_t)(void *)str);
}
- Don Kinzer
ndudman
Posts: 79
Joined: 25 December 2008, 14:00 PM

Post by ndudman »

Thanks again

Pleased that i wasnt too far off... but really helped to iron out those things for me.

Regards
Neil
Post Reply