SlideShare a Scribd company logo
CHAPTER
FIFTYEIGHT
CODE GENERATOR FOR WRAPPING C/C++ LIBRARIES
In this chapter we will learn how to use the code generator to wrap C/C++ Libraries to use it in our Ring applications.
58.1 Using the tool
The code generator program is parsec.ring that can be executed as any ring code using the ring language.
URL : https://github.com/ring-lang/ring/tree/master/extensions/codegen
for example to read a configuration file called test.cf to generate the source code file test.c run parsec.ring as in the
next command
ring parsec.ring test.cf test.c
58.2 Configuration file
The configuration file (*.cf) is the input file that we pass to the code generator. This file determine the functions
prototypes that we need to use from a C/C++ library.
Writing configuration files is simple according to the next rules
58.3 Using the function prototype
• To generate code that wraps a C function, we just write the C function prototype
Example:
ALLEGRO_DISPLAY *al_create_display(int w, int h)
void al_destroy_display(ALLEGRO_DISPLAY *display)
int al_get_new_display_flags(void)
void al_set_new_display_flags(int flags)
int al_get_new_display_option(int option, int *importance)
The previous example will guide the code generator to generate 5 functions that wraps the al_create_display(),
al_destroy_display(), al_get_new_display_flags(), al_set_new_diplay_flas() and al_get_new_display_option() func-
tions.
The generated code will be as in the next example
560
Ring Documentation, Release 1.2
RING_FUNC(ring_al_create_display)
{
if ( RING_API_PARACOUNT != 2 ) {
RING_API_ERROR(RING_API_MISS2PARA);
return ;
}
if ( ! RING_API_ISNUMBER(1) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
if ( ! RING_API_ISNUMBER(2) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
RING_API_RETCPOINTER(al_create_display( (int ) RING_API_GETNUMBER(1),
(int ) RING_API_GETNUMBER(2)),"ALLEGRO_DISPLAY");
}
RING_FUNC(ring_al_destroy_display)
{
if ( RING_API_PARACOUNT != 1 ) {
RING_API_ERROR(RING_API_MISS1PARA);
return ;
}
if ( ! RING_API_ISPOINTER(1) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
al_destroy_display((ALLEGRO_DISPLAY *) RING_API_GETCPOINTER(1,"ALLEGRO_DISPLAY"));
}
RING_FUNC(ring_al_get_new_display_flags)
{
if ( RING_API_PARACOUNT != 0 ) {
RING_API_ERROR(RING_API_BADPARACOUNT);
return ;
}
RING_API_RETNUMBER(al_get_new_display_flags());
}
RING_FUNC(ring_al_set_new_display_flags)
{
if ( RING_API_PARACOUNT != 1 ) {
RING_API_ERROR(RING_API_MISS1PARA);
return ;
}
if ( ! RING_API_ISNUMBER(1) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
al_set_new_display_flags( (int ) RING_API_GETNUMBER(1));
}
RING_FUNC(ring_al_get_new_display_option)
58.3. Using the function prototype 561
Ring Documentation, Release 1.2
{
if ( RING_API_PARACOUNT != 2 ) {
RING_API_ERROR(RING_API_MISS2PARA);
return ;
}
if ( ! RING_API_ISNUMBER(1) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
if ( ! RING_API_ISSTRING(2) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
RING_API_RETNUMBER(al_get_new_display_option( (int ) RING_API_GETNUMBER(1),
RING_API_GETINTPOINTER(2)));
RING_API_ACCEPTINTVALUE(2) ;
}
from the previous example we can see how much of time and effort is saved using the Code Generator.
58.4 Adding code to the generated code
• To generate code directly type it between <code> and </code>
Example :
<code>
/* some C code will be written here */
</code>
We use this feature when we need to do something without the help of the code generator. for example including
header files and defining constants using Macro.
58.5 Prefix for Functions Names
• To determine a prefix in all of the functions names type it between <funcstart> and </funcstart> for ex-
ample when we wrap the Allegro game programming library and we need all of the library functions
to start with “al” we type the next code in the configuration file
<funcstart>
al
</funcstart>
58.6 Generate function to wrap structures
• To generate functions that wrap structures (create/delete/get structure members)
just type the structures names between <struct> and </struct> also after the structure name you can type the structure
members between { } separated by comma.
Example
58.4. Adding code to the generated code 562
Ring Documentation, Release 1.2
<struct>
ALLEGRO_COLOR
ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y }
</struct>
from the previous example we will generate two function to create/delete the structure ALLEGRO_COLOR Also we
will generate two functions to create/delete the structure ALLEGRO_EVENT and four functions to get the structure
ALLEGRO_EVENT members (type, keyboard.keycode, mouse.x, mouse.y).
58.7 Determine Structure Members Types
You can determine the pointer name before the strucuture member name.
Example:
SDL_Surface {flags,SDL_PixelFormat *format,w,h,pitch,void *pixels,void *userdata,locked,void *lock_da
58.8 Defining Contants
You can define constatants using <constant> and </constant>
The generator will generate the required functions to get the constant values
And will define the constants to be used with the same name in Ring code using *.rh file that will be generated too.
rh = Ring Header
Example:
<constant>
MIX_DEFAULT_FORMAT
SDL_QUIT
SDL_BUTTON_LEFT
SDL_BUTTON_MIDDLE
SDL_BUTTON_RIGHT
</constant>
Note: You will need to pass the *.rh file name to parsec.ring after the generated source file name.
Example:
ring ..codegenparsec.ring libsdl.cf ring_libsdl.c ring_libsdl.rh
58.9 Register New Functions
We can register functions by typing the function prototype between <register> and </register> We need this feature
only when we don’t provide the function prototype as input directly where we need to write the code of this function.
Example:
<register>
void al_exit(void)
</register>
58.7. Determine Structure Members Types 563
Ring Documentation, Release 1.2
<code>
RING_FUNC(ring_al_exit)
{
if ( RING_API_PARACOUNT != 0 ) {
RING_API_ERROR(RING_API_BADPARACOUNT);
return ;
}
exit(0);
}
</code>
In the previous example we register the al_exit() function. This function is not part of the Allegro Library, it’s just an
extra function that we need to add. Then the code if this function is written inside <code> and </code>. This function
call the exit() function from the C language library.
58.10 Writing comments in the configuration file
• To type comments just type it between <comment> and </comment>
Example:
<comment>
configuration files
</comment>
58.11 Executing code during code generation
• To ask from the code generator to execute Ring code during reading the configuration file, just
write the code between <runcode> and </runcode>
Example:
<runcode>
aNumberTypes + "al_fixed"
</runcode>
The previoud line of code add the string “al_fixed” to the list aNumberTypes, This list contains types that can be
considered as numbers when the code generator find it in the function prototype.
58.12 Enum and Numbers
We have the list aEnumTypes to use for adding each Enumeration we uses in the functions prototype.
Example:
<runcode>
aNumberTypes + "qreal"
aNumberTypes + "qint64"
aEnumTypes + "Qt::GestureType"
aEnumTypes + "Qt::GestureFlag"
</runcode>
58.10. Writing comments in the configuration file 564
Ring Documentation, Release 1.2
58.13 Filtering using Expressions
using <filter> and </filter> we can include/exclude parts of the configuration file based on a condition, for example
<filter> iswindows()
... functions related to windows
</filter>
58.14 Configuration file for the Allegro Library
The next configuration file enable us to use the Allegro library functions. The configuration file size is less than 1000
lines. when the code generator take this file as input the generated source code file in the C language will be 12000
lines of code!
We can see this configuration file as a complete example about using the code generator Also we can use it to know
the functions that can be used from RingAllegro when you use it to create 2D games!
<code>
#define ALLEGRO_NO_MAGIC_MAIN
#include <allegro5/allegro.h>
#include "allegro5/allegro_image.h"
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <allegro5/allegro_opengl.h>
#include <allegro5/allegro_direct3d.h>
#include <allegro5/allegro_color.h>
#include <allegro5/allegro_memfile.h>
#include "allegro5/allegro_native_dialog.h"
#include <allegro5/allegro_physfs.h>
#include <allegro5/allegro_primitives.h>
</code>
<funcstart>
al
</funcstart>
<struct>
ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y }
ALLEGRO_TIMEOUT
ALLEGRO_SAMPLE_ID
ALLEGRO_COLOR
</struct>
<register>
void al_exit(void)
</register>
<code>
RING_FUNC(ring_al_exit)
{
if ( RING_API_PARACOUNT != 0 ) {
RING_API_ERROR(RING_API_BADPARACOUNT);
return ;
58.13. Filtering using Expressions 565
Ring Documentation, Release 1.2
}
exit(0);
}
</code>
int al_init(void)
<comment>
configuration files
</comment>
<runcode>
aNumberTypes + "al_fixed"
</runcode>
ALLEGRO_CONFIG *al_create_config(void)
void al_destroy_config(ALLEGRO_CONFIG *config)
ALLEGRO_CONFIG *al_load_config_file(const char *filename)
ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file)
bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config)
bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)
void al_add_config_section(ALLEGRO_CONFIG *config, const char *name)
Note: we just provided part of the configuration file, for complete copy check the Ring source code distribution.
58.15 Threads Support
Next, another part of the configutaiton file, it’s important because we can learn from it how to add threads to our Ring
applications by using a threads library.
The idea is using ring_vm_mutexfunctions() and ring_vm_runcodefromthread() to execute Ring code.
<comment>
Threads
</comment>
<code>
void *al_func_thread(ALLEGRO_THREAD *thread, void *pPointer)
{
List *pList;
VM *pVM;
const char *cStr;
pList = (List *) pPointer ;
pVM = (VM *) ring_list_getpointer(pList,2);
cStr = ring_list_getstring(pList,1);
ring_vm_runcodefromthread(pVM,cStr);
ring_list_delete(pList);
return NULL;
}
RING_FUNC(ring_al_create_thread)
{
ALLEGRO_THREAD *pThread;
List *pList;
if ( RING_API_PARACOUNT != 1 ) {
58.15. Threads Support 566
Ring Documentation, Release 1.2
RING_API_ERROR(RING_API_MISS1PARA);
return ;
}
if ( ! RING_API_ISSTRING(1) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
pList = ring_list_new(0);
ring_list_addstring(pList,RING_API_GETSTRING(1));
ring_list_addpointer(pList,pPointer);
ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex,
al_lock_mutex,al_unlock_mutex,al_destroy_mutex);
pThread = al_create_thread(al_func_thread, pList);
al_start_thread(pThread);
RING_API_RETCPOINTER(pThread,"ALLEGRO_THREAD");
}
RING_FUNC(ring_al_run_detached_thread)
{
List *pList;
if ( RING_API_PARACOUNT != 1 ) {
RING_API_ERROR(RING_API_MISS1PARA);
return ;
}
if ( ! RING_API_ISSTRING(1) ) {
RING_API_ERROR(RING_API_BADPARATYPE);
return ;
}
pList = ring_list_new(0);
ring_list_addstring(pList,RING_API_GETSTRING(1));
ring_list_addpointer(pList,pPointer);
ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex,
al_lock_mutex,al_unlock_mutex,al_destroy_mutex);
al_run_detached_thread(al_func_thread, pList);
}
</code>
<register>
ALLEGRO_THREAD *al_create_thread(void)
void al_run_detached_thread(void)
</register>
void al_start_thread(ALLEGRO_THREAD *thread)
void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value)
void al_set_thread_should_stop(ALLEGRO_THREAD *thread)
bool al_get_thread_should_stop(ALLEGRO_THREAD *thread)
void al_destroy_thread(ALLEGRO_THREAD *thread)
ALLEGRO_MUTEX *al_create_mutex(void)
ALLEGRO_MUTEX *al_create_mutex_recursive(void)
void al_lock_mutex(ALLEGRO_MUTEX *mutex)
void al_unlock_mutex(ALLEGRO_MUTEX *mutex)
void al_destroy_mutex(ALLEGRO_MUTEX *mutex)
ALLEGRO_COND *al_create_cond(void)
void al_destroy_cond(ALLEGRO_COND *cond)
void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)
58.15. Threads Support 567
Ring Documentation, Release 1.2
58.16 Code Generator Rules for Wrapping C++ Classes
• We can define classes between <class> and </class>
• Between <class> and <class> we set attributes like “name, nonew, para, parent, codename, passvmpointer and
abstract”
• we set the attributes using the style attributename:value or attributename only if no values are required
• The “name” attribute determine the class name in C++ code and this name will be the default name in the Ring
code
• The nonew instruction means that we don’t need new/delete methods
• The parent attribute determine the parent class name
• The codename attribute determine another class name in C++ code
• The passvmpoint instruction means passing the Ring VM pointer to the class constructor when we create new
objects, this happens when we set the codename attribute to a class the we will define and this class need the
Virtual Machine pointer (for example to use it to execute Ring code from C++ code).
• The abstract instruction means that no new method is required for this class “no objects will be created”.
• Using <nodllstartup> we can avoid #include “ring.h”, We need this to write our startup code.
• Using <libinitfunc> we can change the function name that register the library functions
• Using <ignorecpointertype> we can ignore pointer type check
• Using the aStringTypes list when can defined new types that treated like const char *
• Using the aBeforeReturn list when can define code that is inserted after the variable name when we return that
variable from a function
• Using the aNewMethodName list we can define another method name to be used in Ring code when we call
the C++ method. this feature is required because some C++ method may be identical to Ring Keywords like
“load”,”next”,”end” and “done”.
• in method prototype - when we use @ in the method name, we mean that we have the same method with different
parameters (As in C++)
58.17 Using configuration file that wrap C++ Library
To run the code generator to generate code for using C++ library in the Ring application, we can do that as we did
with using C libraries but here we will generate .cpp file instead of *.c file. Also we will determine another file to be
generated (.ring). This file will contains classes in Ring code that wraps C++ functions for using C++ classes and
objects.
ring parsec.ring qt.cf ring_qt.cpp ring_qt.ring
58.18 Configuration file for the Qt Framework
The next configuration file is used to wrap many Qt classes The configuration file is around 3500 lines and generate
C++ code around 56000 lines and generate also Ring code around 9000 lines.
58.16. Code Generator Rules for Wrapping C++ Classes 568
Ring Documentation, Release 1.2
<nodllstartup>
<libinitfunc> ring_qt_start
<ignorecpointertype>
<code>
extern "C" {
#include "ring.h"
}
#include "ring_qt.h"
#include "gpushbutton.h"
#include "gaction.h"
#include "glineedit.h"
#include "gtextedit.h"
#include "glistwidget.h"
#include "gtreeview.h"
#include "gtreewidget.h"
#include "gcombobox.h"
#include "gtabwidget.h"
#include "gtablewidget.h"
#include "gprogressbar.h"
#include "gspinbox.h"
#include "gslider.h"
#include "gdial.h"
#include "gwebview.h"
#include "gcheckbox.h"
#include "gradiobutton.h"
#include "gbuttongroup.h"
#include "gvideowidget.h"
#include "gtimer.h"
#include "gtcpserver.h"
#include "giodevice.h"
#include "gabstractsocket.h"
#include "gtcpsocket.h"
#include "gcolordialog.h"
#include "gallevents.h"
#include <QApplication>
#include <QObject>
#include <QWidget>
#include <QLabel>
#include <QPixmap>
#include <QIcon>
#include <QSize>
#include <QPushButton>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QTextEdit>
#include <QListWidget>
#include <QTreeView>
#include <QDir>
#include <QFileSystemModel>
#include <QTreeWidget>
#include <QTreeWidgetItem>
58.18. Configuration file for the Qt Framework 569

More Related Content

PDF
The Ring programming language version 1.10 book - Part 97 of 212
PDF
The Ring programming language version 1.9 book - Part 95 of 210
PDF
The Ring programming language version 1.3 book - Part 62 of 88
PDF
The Ring programming language version 1.4 book - Part 22 of 30
PDF
The Ring programming language version 1.6 book - Part 85 of 189
PDF
The Ring programming language version 1.5.1 book - Part 78 of 180
PDF
The Ring programming language version 1.5.2 book - Part 79 of 181
PDF
The Ring programming language version 1.5 book - Part 14 of 31
The Ring programming language version 1.10 book - Part 97 of 212
The Ring programming language version 1.9 book - Part 95 of 210
The Ring programming language version 1.3 book - Part 62 of 88
The Ring programming language version 1.4 book - Part 22 of 30
The Ring programming language version 1.6 book - Part 85 of 189
The Ring programming language version 1.5.1 book - Part 78 of 180
The Ring programming language version 1.5.2 book - Part 79 of 181
The Ring programming language version 1.5 book - Part 14 of 31

What's hot (19)

PDF
The Ring programming language version 1.8 book - Part 91 of 202
PDF
The Ring programming language version 1.5.3 book - Part 91 of 184
PDF
The Ring programming language version 1.7 book - Part 86 of 196
PDF
The Ring programming language version 1.5.4 book - Part 80 of 185
PDF
The Ring programming language version 1.5.1 book - Part 76 of 180
PPTX
Chapter i c#(console application and programming)
PDF
Calculator
PDF
Clean up your code with C#6
PPTX
Java calculator
PDF
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
PPTX
soscon2018 - Tracing for fun and profit
PPTX
Introduction to CDI and DI in Java EE 6
PDF
Eric Lafortune - ProGuard and DexGuard for optimization and protection
PDF
It's complicated, but it doesn't have to be: a Dagger journey
PPTX
Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
PDF
Sony C#/.NET component set analysis
PDF
Dependency Injection with CDI in 15 minutes
PDF
The Ring programming language version 1.6 book - Part 83 of 189
PDF
Qe Reference
The Ring programming language version 1.8 book - Part 91 of 202
The Ring programming language version 1.5.3 book - Part 91 of 184
The Ring programming language version 1.7 book - Part 86 of 196
The Ring programming language version 1.5.4 book - Part 80 of 185
The Ring programming language version 1.5.1 book - Part 76 of 180
Chapter i c#(console application and programming)
Calculator
Clean up your code with C#6
Java calculator
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
soscon2018 - Tracing for fun and profit
Introduction to CDI and DI in Java EE 6
Eric Lafortune - ProGuard and DexGuard for optimization and protection
It's complicated, but it doesn't have to be: a Dagger journey
Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
Sony C#/.NET component set analysis
Dependency Injection with CDI in 15 minutes
The Ring programming language version 1.6 book - Part 83 of 189
Qe Reference
Ad

Viewers also liked (20)

PDF
The Ring programming language version 1.2 book - Part 57 of 84
PDF
The Ring programming language version 1.2 book - Part 76 of 84
PDF
The Ring programming language version 1.2 book - Part 58 of 84
PDF
The Ring programming language version 1.2 book - Part 55 of 84
PDF
The Ring programming language version 1.2 book - Part 54 of 84
PDF
The Ring programming language version 1.2 book - Part 53 of 84
PDF
The Ring programming language version 1.2 book - Part 52 of 84
PDF
The Ring programming language version 1.2 book - Part 75 of 84
PDF
The Ring programming language version 1.2 book - Part 56 of 84
PDF
The Ring programming language version 1.2 book - Part 50 of 84
PDF
The Ring programming language version 1.2 book - Part 73 of 84
PDF
The Ring programming language version 1.2 book - Part 71 of 84
PDF
The Ring programming language version 1.2 book - Part 74 of 84
PDF
The Ring programming language version 1.2 book - Part 70 of 84
PDF
The Ring programming language version 1.2 book - Part 72 of 84
PDF
The Ring programming language version 1.2 book - Part 63 of 84
PDF
The Ring programming language version 1.2 book - Part 62 of 84
PDF
The Ring programming language version 1.2 book - Part 60 of 84
PDF
The Ring programming language version 1.2 book - Part 61 of 84
PDF
The Ring programming language version 1.2 book - Part 78 of 84
The Ring programming language version 1.2 book - Part 57 of 84
The Ring programming language version 1.2 book - Part 76 of 84
The Ring programming language version 1.2 book - Part 58 of 84
The Ring programming language version 1.2 book - Part 55 of 84
The Ring programming language version 1.2 book - Part 54 of 84
The Ring programming language version 1.2 book - Part 53 of 84
The Ring programming language version 1.2 book - Part 52 of 84
The Ring programming language version 1.2 book - Part 75 of 84
The Ring programming language version 1.2 book - Part 56 of 84
The Ring programming language version 1.2 book - Part 50 of 84
The Ring programming language version 1.2 book - Part 73 of 84
The Ring programming language version 1.2 book - Part 71 of 84
The Ring programming language version 1.2 book - Part 74 of 84
The Ring programming language version 1.2 book - Part 70 of 84
The Ring programming language version 1.2 book - Part 72 of 84
The Ring programming language version 1.2 book - Part 63 of 84
The Ring programming language version 1.2 book - Part 62 of 84
The Ring programming language version 1.2 book - Part 60 of 84
The Ring programming language version 1.2 book - Part 61 of 84
The Ring programming language version 1.2 book - Part 78 of 84
Ad

Similar to The Ring programming language version 1.2 book - Part 59 of 84 (20)

PDF
The Ring programming language version 1.7 book - Part 87 of 196
PDF
The Ring programming language version 1.8 book - Part 90 of 202
PDF
The Ring programming language version 1.5.4 book - Part 82 of 185
PDF
The Ring programming language version 1.5.3 book - Part 189 of 194
PDF
The Ring programming language version 1.5.4 book - Part 81 of 185
PDF
The Ring programming language version 1.10 book - Part 102 of 212
PDF
The Ring programming language version 1.5.2 book - Part 176 of 181
PDF
The Ring programming language version 1.5.4 book - Part 180 of 185
PDF
The Ring programming language version 1.3 book - Part 59 of 88
PDF
The Ring programming language version 1.7 book - Part 92 of 196
PDF
The Ring programming language version 1.4 book - Part 21 of 30
PDF
The Ring programming language version 1.8 book - Part 119 of 202
PDF
The Ring programming language version 1.5.2 book - Part 74 of 181
PDF
The Ring programming language version 1.8 book - Part 19 of 202
PDF
The Ring programming language version 1.5.4 book - Part 77 of 185
PDF
The Ring programming language version 1.3 book - Part 8 of 88
PDF
The Ring programming language version 1.5.2 book - Part 14 of 181
PDF
The Ring programming language version 1.9 book - Part 21 of 210
PDF
The Ring programming language version 1.5.3 book - Part 15 of 184
PDF
The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.7 book - Part 87 of 196
The Ring programming language version 1.8 book - Part 90 of 202
The Ring programming language version 1.5.4 book - Part 82 of 185
The Ring programming language version 1.5.3 book - Part 189 of 194
The Ring programming language version 1.5.4 book - Part 81 of 185
The Ring programming language version 1.10 book - Part 102 of 212
The Ring programming language version 1.5.2 book - Part 176 of 181
The Ring programming language version 1.5.4 book - Part 180 of 185
The Ring programming language version 1.3 book - Part 59 of 88
The Ring programming language version 1.7 book - Part 92 of 196
The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.8 book - Part 119 of 202
The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.8 book - Part 19 of 202
The Ring programming language version 1.5.4 book - Part 77 of 185
The Ring programming language version 1.3 book - Part 8 of 88
The Ring programming language version 1.5.2 book - Part 14 of 181
The Ring programming language version 1.9 book - Part 21 of 210
The Ring programming language version 1.5.3 book - Part 15 of 184
The Ring programming language version 1.3 book - Part 84 of 88

More from Mahmoud Samir Fayed (20)

PDF
The Ring programming language version 1.10 book - Part 212 of 212
PDF
The Ring programming language version 1.10 book - Part 211 of 212
PDF
The Ring programming language version 1.10 book - Part 210 of 212
PDF
The Ring programming language version 1.10 book - Part 208 of 212
PDF
The Ring programming language version 1.10 book - Part 207 of 212
PDF
The Ring programming language version 1.10 book - Part 205 of 212
PDF
The Ring programming language version 1.10 book - Part 206 of 212
PDF
The Ring programming language version 1.10 book - Part 204 of 212
PDF
The Ring programming language version 1.10 book - Part 203 of 212
PDF
The Ring programming language version 1.10 book - Part 202 of 212
PDF
The Ring programming language version 1.10 book - Part 201 of 212
PDF
The Ring programming language version 1.10 book - Part 200 of 212
PDF
The Ring programming language version 1.10 book - Part 199 of 212
PDF
The Ring programming language version 1.10 book - Part 198 of 212
PDF
The Ring programming language version 1.10 book - Part 197 of 212
PDF
The Ring programming language version 1.10 book - Part 196 of 212
PDF
The Ring programming language version 1.10 book - Part 195 of 212
PDF
The Ring programming language version 1.10 book - Part 194 of 212
PDF
The Ring programming language version 1.10 book - Part 193 of 212
PDF
The Ring programming language version 1.10 book - Part 192 of 212
The Ring programming language version 1.10 book - Part 212 of 212
The Ring programming language version 1.10 book - Part 211 of 212
The Ring programming language version 1.10 book - Part 210 of 212
The Ring programming language version 1.10 book - Part 208 of 212
The Ring programming language version 1.10 book - Part 207 of 212
The Ring programming language version 1.10 book - Part 205 of 212
The Ring programming language version 1.10 book - Part 206 of 212
The Ring programming language version 1.10 book - Part 204 of 212
The Ring programming language version 1.10 book - Part 203 of 212
The Ring programming language version 1.10 book - Part 202 of 212
The Ring programming language version 1.10 book - Part 201 of 212
The Ring programming language version 1.10 book - Part 200 of 212
The Ring programming language version 1.10 book - Part 199 of 212
The Ring programming language version 1.10 book - Part 198 of 212
The Ring programming language version 1.10 book - Part 197 of 212
The Ring programming language version 1.10 book - Part 196 of 212
The Ring programming language version 1.10 book - Part 195 of 212
The Ring programming language version 1.10 book - Part 194 of 212
The Ring programming language version 1.10 book - Part 193 of 212
The Ring programming language version 1.10 book - Part 192 of 212

Recently uploaded (20)

PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
L1 - Introduction to python Backend.pptx
PDF
medical staffing services at VALiNTRY
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
Introduction to Artificial Intelligence
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
history of c programming in notes for students .pptx
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Nekopoi APK 2025 free lastest update
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
CHAPTER 2 - PM Management and IT Context
L1 - Introduction to python Backend.pptx
medical staffing services at VALiNTRY
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Introduction to Artificial Intelligence
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Wondershare Filmora 15 Crack With Activation Key [2025
Understanding Forklifts - TECH EHS Solution
Reimagine Home Health with the Power of Agentic AI​
history of c programming in notes for students .pptx
Design an Analysis of Algorithms I-SECS-1021-03
Nekopoi APK 2025 free lastest update
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
2025 Textile ERP Trends: SAP, Odoo & Oracle
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Adobe Illustrator 28.6 Crack My Vision of Vector Design
How to Choose the Right IT Partner for Your Business in Malaysia
How to Migrate SBCGlobal Email to Yahoo Easily
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
How Creative Agencies Leverage Project Management Software.pdf

The Ring programming language version 1.2 book - Part 59 of 84

  • 1. CHAPTER FIFTYEIGHT CODE GENERATOR FOR WRAPPING C/C++ LIBRARIES In this chapter we will learn how to use the code generator to wrap C/C++ Libraries to use it in our Ring applications. 58.1 Using the tool The code generator program is parsec.ring that can be executed as any ring code using the ring language. URL : https://github.com/ring-lang/ring/tree/master/extensions/codegen for example to read a configuration file called test.cf to generate the source code file test.c run parsec.ring as in the next command ring parsec.ring test.cf test.c 58.2 Configuration file The configuration file (*.cf) is the input file that we pass to the code generator. This file determine the functions prototypes that we need to use from a C/C++ library. Writing configuration files is simple according to the next rules 58.3 Using the function prototype • To generate code that wraps a C function, we just write the C function prototype Example: ALLEGRO_DISPLAY *al_create_display(int w, int h) void al_destroy_display(ALLEGRO_DISPLAY *display) int al_get_new_display_flags(void) void al_set_new_display_flags(int flags) int al_get_new_display_option(int option, int *importance) The previous example will guide the code generator to generate 5 functions that wraps the al_create_display(), al_destroy_display(), al_get_new_display_flags(), al_set_new_diplay_flas() and al_get_new_display_option() func- tions. The generated code will be as in the next example 560
  • 2. Ring Documentation, Release 1.2 RING_FUNC(ring_al_create_display) { if ( RING_API_PARACOUNT != 2 ) { RING_API_ERROR(RING_API_MISS2PARA); return ; } if ( ! RING_API_ISNUMBER(1) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } if ( ! RING_API_ISNUMBER(2) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } RING_API_RETCPOINTER(al_create_display( (int ) RING_API_GETNUMBER(1), (int ) RING_API_GETNUMBER(2)),"ALLEGRO_DISPLAY"); } RING_FUNC(ring_al_destroy_display) { if ( RING_API_PARACOUNT != 1 ) { RING_API_ERROR(RING_API_MISS1PARA); return ; } if ( ! RING_API_ISPOINTER(1) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } al_destroy_display((ALLEGRO_DISPLAY *) RING_API_GETCPOINTER(1,"ALLEGRO_DISPLAY")); } RING_FUNC(ring_al_get_new_display_flags) { if ( RING_API_PARACOUNT != 0 ) { RING_API_ERROR(RING_API_BADPARACOUNT); return ; } RING_API_RETNUMBER(al_get_new_display_flags()); } RING_FUNC(ring_al_set_new_display_flags) { if ( RING_API_PARACOUNT != 1 ) { RING_API_ERROR(RING_API_MISS1PARA); return ; } if ( ! RING_API_ISNUMBER(1) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } al_set_new_display_flags( (int ) RING_API_GETNUMBER(1)); } RING_FUNC(ring_al_get_new_display_option) 58.3. Using the function prototype 561
  • 3. Ring Documentation, Release 1.2 { if ( RING_API_PARACOUNT != 2 ) { RING_API_ERROR(RING_API_MISS2PARA); return ; } if ( ! RING_API_ISNUMBER(1) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } if ( ! RING_API_ISSTRING(2) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } RING_API_RETNUMBER(al_get_new_display_option( (int ) RING_API_GETNUMBER(1), RING_API_GETINTPOINTER(2))); RING_API_ACCEPTINTVALUE(2) ; } from the previous example we can see how much of time and effort is saved using the Code Generator. 58.4 Adding code to the generated code • To generate code directly type it between <code> and </code> Example : <code> /* some C code will be written here */ </code> We use this feature when we need to do something without the help of the code generator. for example including header files and defining constants using Macro. 58.5 Prefix for Functions Names • To determine a prefix in all of the functions names type it between <funcstart> and </funcstart> for ex- ample when we wrap the Allegro game programming library and we need all of the library functions to start with “al” we type the next code in the configuration file <funcstart> al </funcstart> 58.6 Generate function to wrap structures • To generate functions that wrap structures (create/delete/get structure members) just type the structures names between <struct> and </struct> also after the structure name you can type the structure members between { } separated by comma. Example 58.4. Adding code to the generated code 562
  • 4. Ring Documentation, Release 1.2 <struct> ALLEGRO_COLOR ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y } </struct> from the previous example we will generate two function to create/delete the structure ALLEGRO_COLOR Also we will generate two functions to create/delete the structure ALLEGRO_EVENT and four functions to get the structure ALLEGRO_EVENT members (type, keyboard.keycode, mouse.x, mouse.y). 58.7 Determine Structure Members Types You can determine the pointer name before the strucuture member name. Example: SDL_Surface {flags,SDL_PixelFormat *format,w,h,pitch,void *pixels,void *userdata,locked,void *lock_da 58.8 Defining Contants You can define constatants using <constant> and </constant> The generator will generate the required functions to get the constant values And will define the constants to be used with the same name in Ring code using *.rh file that will be generated too. rh = Ring Header Example: <constant> MIX_DEFAULT_FORMAT SDL_QUIT SDL_BUTTON_LEFT SDL_BUTTON_MIDDLE SDL_BUTTON_RIGHT </constant> Note: You will need to pass the *.rh file name to parsec.ring after the generated source file name. Example: ring ..codegenparsec.ring libsdl.cf ring_libsdl.c ring_libsdl.rh 58.9 Register New Functions We can register functions by typing the function prototype between <register> and </register> We need this feature only when we don’t provide the function prototype as input directly where we need to write the code of this function. Example: <register> void al_exit(void) </register> 58.7. Determine Structure Members Types 563
  • 5. Ring Documentation, Release 1.2 <code> RING_FUNC(ring_al_exit) { if ( RING_API_PARACOUNT != 0 ) { RING_API_ERROR(RING_API_BADPARACOUNT); return ; } exit(0); } </code> In the previous example we register the al_exit() function. This function is not part of the Allegro Library, it’s just an extra function that we need to add. Then the code if this function is written inside <code> and </code>. This function call the exit() function from the C language library. 58.10 Writing comments in the configuration file • To type comments just type it between <comment> and </comment> Example: <comment> configuration files </comment> 58.11 Executing code during code generation • To ask from the code generator to execute Ring code during reading the configuration file, just write the code between <runcode> and </runcode> Example: <runcode> aNumberTypes + "al_fixed" </runcode> The previoud line of code add the string “al_fixed” to the list aNumberTypes, This list contains types that can be considered as numbers when the code generator find it in the function prototype. 58.12 Enum and Numbers We have the list aEnumTypes to use for adding each Enumeration we uses in the functions prototype. Example: <runcode> aNumberTypes + "qreal" aNumberTypes + "qint64" aEnumTypes + "Qt::GestureType" aEnumTypes + "Qt::GestureFlag" </runcode> 58.10. Writing comments in the configuration file 564
  • 6. Ring Documentation, Release 1.2 58.13 Filtering using Expressions using <filter> and </filter> we can include/exclude parts of the configuration file based on a condition, for example <filter> iswindows() ... functions related to windows </filter> 58.14 Configuration file for the Allegro Library The next configuration file enable us to use the Allegro library functions. The configuration file size is less than 1000 lines. when the code generator take this file as input the generated source code file in the C language will be 12000 lines of code! We can see this configuration file as a complete example about using the code generator Also we can use it to know the functions that can be used from RingAllegro when you use it to create 2D games! <code> #define ALLEGRO_NO_MAGIC_MAIN #include <allegro5/allegro.h> #include "allegro5/allegro_image.h" #include <allegro5/allegro_font.h> #include <allegro5/allegro_ttf.h> #include <allegro5/allegro_audio.h> #include <allegro5/allegro_acodec.h> #include <allegro5/allegro_opengl.h> #include <allegro5/allegro_direct3d.h> #include <allegro5/allegro_color.h> #include <allegro5/allegro_memfile.h> #include "allegro5/allegro_native_dialog.h" #include <allegro5/allegro_physfs.h> #include <allegro5/allegro_primitives.h> </code> <funcstart> al </funcstart> <struct> ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y } ALLEGRO_TIMEOUT ALLEGRO_SAMPLE_ID ALLEGRO_COLOR </struct> <register> void al_exit(void) </register> <code> RING_FUNC(ring_al_exit) { if ( RING_API_PARACOUNT != 0 ) { RING_API_ERROR(RING_API_BADPARACOUNT); return ; 58.13. Filtering using Expressions 565
  • 7. Ring Documentation, Release 1.2 } exit(0); } </code> int al_init(void) <comment> configuration files </comment> <runcode> aNumberTypes + "al_fixed" </runcode> ALLEGRO_CONFIG *al_create_config(void) void al_destroy_config(ALLEGRO_CONFIG *config) ALLEGRO_CONFIG *al_load_config_file(const char *filename) ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file) bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config) bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config) void al_add_config_section(ALLEGRO_CONFIG *config, const char *name) Note: we just provided part of the configuration file, for complete copy check the Ring source code distribution. 58.15 Threads Support Next, another part of the configutaiton file, it’s important because we can learn from it how to add threads to our Ring applications by using a threads library. The idea is using ring_vm_mutexfunctions() and ring_vm_runcodefromthread() to execute Ring code. <comment> Threads </comment> <code> void *al_func_thread(ALLEGRO_THREAD *thread, void *pPointer) { List *pList; VM *pVM; const char *cStr; pList = (List *) pPointer ; pVM = (VM *) ring_list_getpointer(pList,2); cStr = ring_list_getstring(pList,1); ring_vm_runcodefromthread(pVM,cStr); ring_list_delete(pList); return NULL; } RING_FUNC(ring_al_create_thread) { ALLEGRO_THREAD *pThread; List *pList; if ( RING_API_PARACOUNT != 1 ) { 58.15. Threads Support 566
  • 8. Ring Documentation, Release 1.2 RING_API_ERROR(RING_API_MISS1PARA); return ; } if ( ! RING_API_ISSTRING(1) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } pList = ring_list_new(0); ring_list_addstring(pList,RING_API_GETSTRING(1)); ring_list_addpointer(pList,pPointer); ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex, al_lock_mutex,al_unlock_mutex,al_destroy_mutex); pThread = al_create_thread(al_func_thread, pList); al_start_thread(pThread); RING_API_RETCPOINTER(pThread,"ALLEGRO_THREAD"); } RING_FUNC(ring_al_run_detached_thread) { List *pList; if ( RING_API_PARACOUNT != 1 ) { RING_API_ERROR(RING_API_MISS1PARA); return ; } if ( ! RING_API_ISSTRING(1) ) { RING_API_ERROR(RING_API_BADPARATYPE); return ; } pList = ring_list_new(0); ring_list_addstring(pList,RING_API_GETSTRING(1)); ring_list_addpointer(pList,pPointer); ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex, al_lock_mutex,al_unlock_mutex,al_destroy_mutex); al_run_detached_thread(al_func_thread, pList); } </code> <register> ALLEGRO_THREAD *al_create_thread(void) void al_run_detached_thread(void) </register> void al_start_thread(ALLEGRO_THREAD *thread) void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value) void al_set_thread_should_stop(ALLEGRO_THREAD *thread) bool al_get_thread_should_stop(ALLEGRO_THREAD *thread) void al_destroy_thread(ALLEGRO_THREAD *thread) ALLEGRO_MUTEX *al_create_mutex(void) ALLEGRO_MUTEX *al_create_mutex_recursive(void) void al_lock_mutex(ALLEGRO_MUTEX *mutex) void al_unlock_mutex(ALLEGRO_MUTEX *mutex) void al_destroy_mutex(ALLEGRO_MUTEX *mutex) ALLEGRO_COND *al_create_cond(void) void al_destroy_cond(ALLEGRO_COND *cond) void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex) 58.15. Threads Support 567
  • 9. Ring Documentation, Release 1.2 58.16 Code Generator Rules for Wrapping C++ Classes • We can define classes between <class> and </class> • Between <class> and <class> we set attributes like “name, nonew, para, parent, codename, passvmpointer and abstract” • we set the attributes using the style attributename:value or attributename only if no values are required • The “name” attribute determine the class name in C++ code and this name will be the default name in the Ring code • The nonew instruction means that we don’t need new/delete methods • The parent attribute determine the parent class name • The codename attribute determine another class name in C++ code • The passvmpoint instruction means passing the Ring VM pointer to the class constructor when we create new objects, this happens when we set the codename attribute to a class the we will define and this class need the Virtual Machine pointer (for example to use it to execute Ring code from C++ code). • The abstract instruction means that no new method is required for this class “no objects will be created”. • Using <nodllstartup> we can avoid #include “ring.h”, We need this to write our startup code. • Using <libinitfunc> we can change the function name that register the library functions • Using <ignorecpointertype> we can ignore pointer type check • Using the aStringTypes list when can defined new types that treated like const char * • Using the aBeforeReturn list when can define code that is inserted after the variable name when we return that variable from a function • Using the aNewMethodName list we can define another method name to be used in Ring code when we call the C++ method. this feature is required because some C++ method may be identical to Ring Keywords like “load”,”next”,”end” and “done”. • in method prototype - when we use @ in the method name, we mean that we have the same method with different parameters (As in C++) 58.17 Using configuration file that wrap C++ Library To run the code generator to generate code for using C++ library in the Ring application, we can do that as we did with using C libraries but here we will generate .cpp file instead of *.c file. Also we will determine another file to be generated (.ring). This file will contains classes in Ring code that wraps C++ functions for using C++ classes and objects. ring parsec.ring qt.cf ring_qt.cpp ring_qt.ring 58.18 Configuration file for the Qt Framework The next configuration file is used to wrap many Qt classes The configuration file is around 3500 lines and generate C++ code around 56000 lines and generate also Ring code around 9000 lines. 58.16. Code Generator Rules for Wrapping C++ Classes 568
  • 10. Ring Documentation, Release 1.2 <nodllstartup> <libinitfunc> ring_qt_start <ignorecpointertype> <code> extern "C" { #include "ring.h" } #include "ring_qt.h" #include "gpushbutton.h" #include "gaction.h" #include "glineedit.h" #include "gtextedit.h" #include "glistwidget.h" #include "gtreeview.h" #include "gtreewidget.h" #include "gcombobox.h" #include "gtabwidget.h" #include "gtablewidget.h" #include "gprogressbar.h" #include "gspinbox.h" #include "gslider.h" #include "gdial.h" #include "gwebview.h" #include "gcheckbox.h" #include "gradiobutton.h" #include "gbuttongroup.h" #include "gvideowidget.h" #include "gtimer.h" #include "gtcpserver.h" #include "giodevice.h" #include "gabstractsocket.h" #include "gtcpsocket.h" #include "gcolordialog.h" #include "gallevents.h" #include <QApplication> #include <QObject> #include <QWidget> #include <QLabel> #include <QPixmap> #include <QIcon> #include <QSize> #include <QPushButton> #include <QMainWindow> #include <QVBoxLayout> #include <QHBoxLayout> #include <QLineEdit> #include <QTextEdit> #include <QListWidget> #include <QTreeView> #include <QDir> #include <QFileSystemModel> #include <QTreeWidget> #include <QTreeWidgetItem> 58.18. Configuration file for the Qt Framework 569