Author Topic: thinBasic Modular Interface / strings  (Read 159 times)

0 Members and 1 Guest are viewing this topic.

Eros Olmi

  • Newbie
  • *
  • Posts: 21
thinBasic Modular Interface / strings
« on: June 28, 2018, 11:06:42 AM »
Ciao Charles,

is Oxygen string data type a BSTR string like in PowerBasic?
Its seems to work like it is.

Thanks
Eros

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3719
    • Oxygen Basic
Re: thinBasic Modular Interface / strings
« Reply #1 on: June 28, 2018, 09:01:28 PM »
Yes, Eros.

O2 uses bstring / bstr for its underlying string type, and also for all its dynamic memory allocations.

But there appears to be a problem with o2 string literals, which are pseudo-bstrings stored in o2's global space.

thinBasic_LoadSymbol will not accept them directly, so I have to pass them as string variables.

Code: [Select]
  string na[]=
  {
    "O2_Abst",    '1
    "O2_Asmo",    '2
    "O2_Basic",   '3
    "O2_Buf",     '4
    "O2_Errno",   '5
    "O2_Error",   '6
    "O2_Eval",    '7
    "O2_Exec",    '8
    "O2_Len",     '9
    "O2_Link",    '10
    "O2_Prep",    '11
    "O2_View",    '12
    "Oxygen_Eval",'13
    "O2_Version"  '14
    '"O2_Asm" obsolete
    '"O2_Get" obsolete
    '"O2_Put" obsolete
  }
  '
  indexbase 1
  thinBasic_LoadSymbol (na[ 1], thinBasic_ReturnString,   @tbo2_Abst,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 2], thinBasic_ReturnNone,     @tbo2_Asmo,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 3], thinBasic_ReturnNone,     @tbo2_Basic, thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 4], thinBasic_ReturnCodeLong, @tbO2_Buf,   thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 5], thinBasic_ReturnCodeLong, @tbo2_Errno, thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 6], thinBasic_ReturnString,   @tbo2_Error, thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 7], thinBasic_ReturnString,   @tbo2_Link,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 8], thinBasic_ReturnCodeLong, @tbO2_Exec,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[ 9], thinBasic_ReturnCodeLong, @tbO2_Len,   thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[10], thinBasic_ReturnString,   @tbo2_Link,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[11], thinBasic_ReturnString,   @tbo2_Prep,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[12], thinBasic_ReturnString,   @tbo2_View,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[13], thinBasic_ReturnString,   @tbo2_Link,  thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol (na[14], thinBasic_ReturnString,   @tbo2_Version,  thinBasic_ForceOverWrite)
  End Function




Eros Olmi

  • Newbie
  • *
  • Posts: 21
Re: thinBasic Modular Interface / strings
« Reply #2 on: June 28, 2018, 10:26:23 PM »
Thanks Charles.
Great, it will all be much more easy for me to use Oxygen for developing thinBasic modules and to show to thinBasic users some tutorials on how to do it.

Yes, I started to study Oxygen wrapper module you developed and saw you declared a string array instead of string literals  to be able to pass module function names.
Anyway in my tests I just used string literals in thinBasic_LoadSymbol and they seem working fine.
« Last Edit: June 28, 2018, 11:05:57 PM by Eros Olmi »

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3719
    • Oxygen Basic
Re: thinBasic Modular Interface / strings
« Reply #3 on: June 29, 2018, 12:55:43 AM »
I found the string literals to be erratic. Sometimes they work, and sometimes they don't.  It may be due to lack of dword-alignment. o2's string constants are currently packed without alignment. I can insert alignment directives for all o2 string literals. I will see if this makes any difference.

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3719
    • Oxygen Basic
Re: thinBasic Modular Interface / strings
« Reply #4 on: June 29, 2018, 08:59:49 AM »
Yes!

thinBasic_LoadSymbol accepts dword-aligned pseudo-bstrings.

I have posted the updates on Github.

This is my latest revision of thinBasic_Oxygen.dll. It is not quite so low-level, and demonstrates how to late-bind to a DLL. In this case, Oxygen.dll with its location given by spath.

Code: [Select]
  'COMPILING WITH OXYGEN
  '11:08 13/12/2013
  '12:01 29/06/2018
  'Charles E V Pegge
  '
  $ dll
  $ filename "thinBasic_Oxygen.dll"
  uses RTL32

  % late_binding
  % TB_TRUE  1
  % TB_FALSE 0

  ' Return Types from functions/Subs
  '=================================

  % thinBasic_ReturnNone          0  'Used in thinBasic_LoadSymbol to define a sub
  % thinBasic_ReturnNumber       20  'Used in thinBasic_LoadSymbol to define a function returning a EXT number
  % thinBasic_ReturnString       30  'Used in thinBasic_LoadSymbol to define a function returning a string
  % thinBasic_ReturnCodeByte      1
  % thinBasic_ReturnCodeInteger   2
  % thinBasic_ReturnCodeWord      3
  % thinBasic_ReturnCodeDWord     4
  % thinBasic_ReturnCodeLong      5
  % thinBasic_ReturnCodeQuad      6
  % thinBasic_ReturnCodeSingle    7
  % thinBasic_ReturnCodeDouble    8
  % thinBasic_ReturnCodeCurrency  9
  % thinBasic_ReturnCodeExt      10
  % thinBasic_ReturnCodeString   30
  % thinBasic_ForceOverWrite      1  'Used in thinBasic_LoadSymbol to force symbol over writing

  extern stdcall lib "thinCore.dll"
  =================================

  ! thinBasic_ParseLong                  (sys*sResult)
  ! thinBasic_ParseString                (string*sResult) as double
  ! thinBasic_CheckOpenParens_Optional   () as sys
  ! thinBasic_CheckCloseParens_Mandatory () as sys
  ! thinBasic_GetRunTimeInfo             (string InfoName) as string
  ! thinBasic_VariableGetInfoEX          (string SearchKey, sys *pMainType,*pSubType,*pIsArray,*pDataPtr,*pnElements,WhichLevel) as sys
  ! thinBasic_LoadSymbol                 (string SymbolName,sys ReturnCode,FunctionOrSubPointer,ForceOverWrite) as sys

  end extern

  sys oxygen
  sys ParensPresent
  string src,cod
  double dv
  '
  extern stdcall
  ==============
  '
  'DECLARATIONS FOR LATE BINDING TO OXYGEN.DLL
  '
  !* o2_abst      (string s) as string
  !* o2_asmo      (string s) as sys
  !* o2_basic     (string s) as sys
  !* o2_exec      (sys p=0)  as sys
  !* o2_buf       (sys n)    as sys
  !* o2_errno      ()         as sys
  !* o2_error     ()         as string
  !* o2_len       ()         as sys
  !* o2_lib       ()         as sys
  !* o2_link      (string s) as sys
  !* o2_mode      (sys m)
  !* o2_pathcall  (sys m)
  !* o2_prep      (string s) as string
  !* o2_varcall   (sys m)
  !* o2_version   () as string
  !* o2_view      (string s) as string


  function GetvarPtr(char*z) as sys, callback
  ===========================================
  '
  string VarName=z
  sys MainType, SubType, IsArray, DataPtr, nElements, WhichLevel
  thinBasic_VariableGetInfoEX Varname, MainType, SubType, IsArray,
    DataPtr, nElements, WhichLevel
  return DataPtr
  end function


  'Function GetRuntimeInfo(char*z) as sys
  '======================================
  '
  'static string n=z
  ''n="APP_PATH" ' also "SCRIPT_PATH"  "HWND"
  'n=thinBasic_GetRunTimeInfo(n)
  'return strptr n
  'End Function


  Function inclpath(char*z) as char*
  ==================================
  '
  static string wd
  static string pth="APP_PATH"
  wd=lcase z
  if left(wd,17)="%app_includepath%" then
    wd=thinBasic_GetRuntimeInfo(pth)+"inc"+mid(wd,18)
  end if
  return wd
  end Function


  #define  HOSTED


  Function tbo2_len() as sys
  ==========================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  Function = call o2_len
  End Function


  Function tbo2_buf() as sys
  ==========================
  '
  sys p
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  thinBasic_ParseLong(p)
  function=call o2_buf p
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  End Function


  Function tbo2_exec() as sys
  ===========================
  '
  sys p
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  If ParensPresent = TB_TRUE Then
    dv=thinBasic_ParseString(cod)
    p=strptr cod
    thinBasic_CheckCloseParens_Mandatory()
  end if
  function=o2_exec p
  End Function


  Function tbO2_Link() as sys
  ===========================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  dv=thinBasic_ParseString(src)
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  return call o2_link src
  End Function


  sub tbo2_Asmo()
  ===============
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  dv=thinBasic_ParseString(src)
  call o2_asmo src
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  End Sub


  sub tbO2_BASIC()
  ================
  '
  tbo2_asmo()
  end sub


  Function tbo2_View() as sys
  ===========================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  dv=thinBasic_ParseString(src)
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  return call o2_view src
  End Function


  Function tbo2_Prep() as sys
  ===========================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  dv=thinBasic_ParseString(src)
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  return call o2_prep src
  End Function


  Function tbo2_Abst() as sys
  ===========================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  dv=thinBasic_ParseString(src)
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  return call o2_abst src
  End Function


  Function tbo2_Error() as sys
  ============================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  return call o2_error
  End Function


  Function tbo2_Errno() as sys
  '===========================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  return call o2_errno
  End Function


  Function tbo2_Version() as sys
  ==============================
  '
  ParensPresent = thinBasic_CheckOpenParens_Optional()
  If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory()
  return call o2_version
  End Function


  Function finish() external
  ==========================
  if oxygen then FreeLibrary oxygen
  terminate
  End Function




  Function LoadLocalSymbols cdecl (string sPath) as sys, export
  =============================================================

  /*
  This function is automatically called by thinCore whenever this DLL module is loaded.
  This function MUST (repeat MUST) be present in every external DLL module you want to use
  with thinBasic
  Use this function to initialize every you need and for loading the
  new symbol (read Keyword) you have created.
  */
  'LATE BINDING TO OXYGEN.DLL
  '
  oxygen=loadlibrary spath+"oxygen.dll"
  '
  if oxygen=0
    print "Oxygen.dll not here: " spath
    exit function
  end if
  '
  def lp
    @%1=GetProcAddress oxygen,"%1"
  end def
  '
  lp o2_mode
  lp o2_len
  lp o2_buf
  lp o2_exec
  lp o2_lib
  lp o2_link
  lp o2_asmo
  lp o2_basic
  lp o2_abst
  lp o2_prep
  lp o2_view
  lp o2_error
  lp o2_errno
  lp o2_varcall
  lp o2_pathcall
  lp o2_version
  '
  o2_mode(9) 'bstrings UTF8
  o2_varcall  @GetVarPtr 'var callback pointer. proc for passing host variable name and returning variable pointer
  o2_pathcall @InclPath  'path callback to get path
  '
  string mdl_path=spath

  thinBasic_LoadSymbol ("O2_Abst",     thinBasic_ReturnString,   @tbo2_Abst,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Asmo",     thinBasic_ReturnNone,     @tbo2_Asmo,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Basic",    thinBasic_ReturnNone,     @tbo2_Basic,   thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Buf",      thinBasic_ReturnCodeLong, @tbO2_Buf,     thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Errno",    thinBasic_ReturnCodeLong, @tbo2_Errno,   thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Error",    thinBasic_ReturnString,   @tbo2_Error,   thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Eval",     thinBasic_ReturnString,   @tbo2_Link,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Exec",     thinBasic_ReturnCodeLong, @tbO2_Exec,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Len",      thinBasic_ReturnCodeLong, @tbO2_Len,     thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Link",     thinBasic_ReturnString,   @tbo2_Link,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Prep",     thinBasic_ReturnString,   @tbo2_Prep,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_View",     thinBasic_ReturnString,   @tbo2_View,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("Oxygen_Eval", thinBasic_ReturnString,   @tbo2_Link,    thinBasic_ForceOverWrite)
  thinBasic_LoadSymbol ("O2_Version",  thinBasic_ReturnString,   @tbo2_Version, thinBasic_ForceOverWrite)
  End Function


  Function UnLoadLocalSymbols cdecl (string sPath) as sys, export
  ===============================================================
  End Function

  end extern

« Last Edit: June 29, 2018, 09:12:11 AM by Charles Pegge »

Eros Olmi

  • Newbie
  • *
  • Posts: 21
Re: thinBasic Modular Interface / strings
« Reply #5 on: June 29, 2018, 10:07:19 AM »
Great, thanks a lot Charles.
I will maintain thinBasic_Oxygen.dll module ... I think I will use Oxygen compiler a lot so I hope to get some of its secrets :)
« Last Edit: June 29, 2018, 07:28:03 PM by Eros Olmi »