Author Topic: Creating a wrapper file  (Read 3512 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Guest
Creating a wrapper file
« on: April 22, 2015, 10:57:29 PM »
Hi Charles,

I am trying to create a helper template for wrapping C header files. The idea is to build a basic include file which can be edited by hand afterwards. It uses some patterns which are substituted. Comparing your inc\glo2\freeglut.inc with the latest freeglut header files I tried to rebuild freeglut.inc with as few changes as possible.

This is the code which I applied to create freeglut.inc, it also works with version A40:

Code: OxygenBasic
  1. /* Wrapper for freeglut libray include files
  2.    uses freeglut_std.h
  3.    uses freeglut_ext.h
  4. */  
  5.    
  6. % filename "WrapFreeglut.exe"
  7. 'include "$\inc\rtl32.inc"
  8.  
  9. include "$\inc\console.inc"
  10. include "$\inc\stringutil.inc"
  11.  
  12. print "start wrapping:" cr
  13.  
  14. indexbase 1
  15.  
  16. string outfile = "freeglut.inc"
  17. dim as string infile() => {
  18. "freeglut_std.h",
  19. "freeglut_ext.h"
  20. }
  21. % num_of_infile = spanof(infile)
  22.  
  23. string intro =
  24. "'Wrapped for use with OxygenBasic" & cr &
  25. "'Version " & version & cr
  26.  
  27. string prolog
  28.  
  29. string appendix =
  30. cr & "end extern" & cr "'print " & chr(34) & "ok" & chr(34) & cr
  31.  
  32. ' code to replace
  33. type subst1
  34.   string org
  35.   string repl
  36. end type
  37.  
  38. subst1 code[] => {
  39. {"#define", "%"},
  40. {"FGAPIENTRY ", ""},
  41. {"FGAPI ", ""},
  42. {"GLUTproc ","sys "},
  43. {"#elif __APPLE__", "'#elif __APPLE__"},
  44. {"( void )", "()"},
  45. {"(void)", "()"},
  46. {"#include", "' #include"},
  47. {";", ""}
  48. }
  49.  
  50. ' code with 2 replaces
  51. type subst2
  52.   string org
  53.   string repl
  54.   string end_org
  55.   string end_repl
  56. end type
  57.  
  58. subst2 code2[] => {
  59. {"extern void*", "sys", "", "()"},  '4th arg append
  60. {"((void *) &", "", ")", " "},      '4th arg replace
  61. {"((void *)", "", ")", " "}         '4th arg replace
  62. }
  63.  
  64. dim as string buffer[num_of_infile]
  65. dim as string Lines[10000]
  66.  
  67. int lastline = 0
  68.  
  69.  
  70. sub split_lines(string buffer)
  71.    ' LineSplitter1.o2bas
  72.  
  73.    indexbase 1
  74.  
  75.    sys idx, jdx              'indexes
  76.  
  77.    'initial
  78.   '=======
  79.  
  80.    lines={32}
  81.    begin=1  'start of line
  82.   idx=0  'lines array index
  83.   jdx=1  'char index
  84.  
  85.    byte address at (strptr buffer)
  86.  
  87.    'splitter loop
  88.   '=============
  89.  
  90.    do
  91.      select address
  92.      case 0
  93.        if jdx-begin>0 then
  94.          idx++
  95.          lines[idx]=mid(buffer,begin,jdx-begin)
  96.        end if
  97.        exit do
  98.      case 10 'LF TERMINATED LINES
  99.       idx++
  100.        lines[idx]=mid(buffer,begin,jdx-begin)
  101.        begin=jdx+1
  102.      case 13 'CR AND CRLF TERMINATED LINES
  103.       idx++
  104.        lines[idx]=mid(buffer,begin,jdx-begin)
  105.        if address[2]=10 then @address++ : jdx++ 'SKIP LF
  106.       begin=jdx+1
  107.      end select
  108.      @address++ 'inc pointer for address
  109.     jdx++
  110.    end do
  111.    LastLine=idx
  112.  
  113. end sub
  114.  
  115. '--------------------------------------
  116. ' start editing the files
  117.  
  118. for fn = 1 to num_of_infile
  119.    ' load header file
  120.   getfile(infile[fn] , buffer[fn])
  121.    if buffer[fn] = "" then
  122.       print infile[fn] & " not found or empty!" cr: goto finish
  123.    end if
  124.  
  125.    split_lines(buffer[fn])
  126.    if LastLine<1 then
  127.       print "Error in File: " infile[fn] & cr: goto finish
  128.    end if
  129.    buffer[fn] =""
  130.  
  131.    ' replace under some conditions
  132.   for x = 1 to LastLine
  133.       lines[x] = ltrim rtrim lines[x]
  134.       if left(lines[x],1) = "#" then lines[x] = "#" & ltrim mid(lines[x],2)
  135.      
  136.       for y = 1 to spanof(code)
  137.          lines[x] = replace (lines[x], code[y].org, code[y].repl )
  138.       next y
  139.      
  140.       for y = 1 to spanof(code2)
  141.          if instr(lines[x], code2[y].org) then
  142.             lines[x] = replace (lines[x], code2[y].org, code2[y].repl )
  143.             if code2[y].end_org = "" then
  144.                'append
  145.               lines[x] &= code2[y].end_repl
  146.             else
  147.                'replace
  148.               mid lines[x], len(lines[x]), code2[y].end_repl
  149.             end if
  150.          end if
  151.       next y
  152.  
  153.    next x
  154.    
  155.    ' update buffer
  156.   for x = 1 to Lastline
  157.       buffer[fn] &= lines[x] & cr
  158.    next x
  159.    
  160. next fn
  161.  
  162. '--------------------------------------
  163. ' put the files together
  164.  
  165. getfile ("prolog.txt", prolog)
  166.  
  167. string buff = intro & cr & prolog & cr
  168. for x = 1 to num_of_infile
  169.    buff &= buffer[x]
  170. next x
  171. buff &= appendix
  172.  
  173. putfile outfile, buff                  
  174.  
  175.  
  176. finish:
  177. print "ready"
  178. waitkey()
  179.  

I renamed freeglut.inc in the \inc\glo2 folder and used the new freeglut.inc. As the demos worked as expected, I assume that the wrapped file is ok, although I did not comment out the preprocessor statements in most cases.

Unfortunately I am not really able to use stringutil.inc more effectively. Could you show me how I can apply TextArray? Probably I will not need the function split_lines and the statements for loading / saving the buffers and modifying the lines must be different? But I assume that the code could be reduced by some lines.


Roland

.

Charles Pegge

  • Guest
Re: Creating a wrapper file
« Reply #1 on: April 23, 2015, 06:18:12 AM »
Hi Roland,

Do you need to split into lines? A simple Getfile --> replace words --> PutFile  will do the main part of the job.

Arnold

  • Guest
Re: Creating a wrapper file
« Reply #2 on: April 23, 2015, 11:20:28 AM »
Hi Charles,

thank you for the hint. I will rework the code without splitting the buffers into lines.

Roland

Arnold

  • Guest
Re: Creating a wrapper file
« Reply #3 on: April 24, 2015, 04:06:57 AM »
Hi Charles,

please excuse my ignorance. Sometimes I am a little bit slow-witted. I tried to use the header files unchanged and only minor modifications were requested by OxygenBasic. These are the changes:


'#elif __APPLE__

'#   include <GL/gl.h>
'#   include <GL/glu.h>

'#include <stdlib.h>

'typedef void (*GLUTproc)();
#define GLUTproc sys

'#include <stdarg.h>


and the Freeglut demos worked as expected. Of course I do not need a wrapper for this changing. I was curious about the remaining differences in the original freeglut.inc and found these places:


#   define  GLUT_STROKE_ROMAN               ((void *)0x0000)
-->   %  GLUT_STROKE_ROMAN               0x0000

    extern void* glutStrokeRoman;
--> sys glutStrokeRoman()

#   define  GLUT_STROKE_ROMAN               ((void *) &glutStrokeRoman)
--> %  GLUT_STROKE_ROMAN               glutStrokeRoman

'typedef void (*GLUTproc)();
#define GLUTproc sys
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
-->
'typedef void (*GLUTproc)()
'GLUTproc glutGetProcAddress( const char *procName )
sys glutGetProcAddress( const char *procName )


The modification for typedef *Glutproc is required. Are the first three modifications necessary too or is this an option? And are there some more conditions which must be observed?

I know that in some other programming languages sometimes a laborious workaround is necessary to access functions of a dll. If it is possible to use a C-header file with only little effort then this is indeed a very powerful feature.


Roland



.

Charles Pegge

  • Guest
Re: Creating a wrapper file
« Reply #4 on: April 24, 2015, 07:03:23 AM »

Hi Roland,

Most of those are simple exclusions of undefined symbols, but the last one, I should be able to improve upon.

typedef void (*GLUTproc)()
GLUTproc glutGetProcAddress( const char *procName )


Arnold

  • Guest
Re: Creating a wrapper file
« Reply #5 on: April 26, 2015, 08:11:49 AM »
Hi Charles,

in order to experiment a bit with dll and header files I tried to use the GLFW3 library. I know nothing about OpenGL or GLFW but using the header file seems to be rather easy. I removed the comments, preprocessor directives and the GLFWApi placeholders for creating the include file. Unfortunately the GLFW3 library seems to produce memory leaks (checking with taskmanager). I found this issue also mentioned in Internet so this library is not useful for me until the problem is fixed. But perhaps you find in the include file some combinations (starting at about line 360) which may be of interest. I append the files with some demos because of another question:

In the include file I can use "extern lib" with these statements:

extern lib "$/lib/glfw3.dll"  when copying the dll into the lib folder of OxygenBasic
extern lib "c:\GLFW3\dll/glfw3.dll"   when using an absolute path

statements using relative paths like:

extern lib "lib/glfw3.dll"
extern lib "../dll/glfw3.dll"

seem not to work. Is there a trick to use a relative path for a dll in an include file? I saw that in the Iup demos "Iup/Iup.dll" is used but this happens in the main .o2bas files.

Roland


.