Hi,or a config file the program reads at startup. I want users to issue commands like:
I was wondering for the best way to make c and c++ data structures accesible to tcl running as a script engine for a c/c++ program.
The idea is to give scripting capabilities to a C/C++ program using tcl as a extension scripting language in a way users can control the main program using tcl. So I need to access data structures (structs, classes...) from tcl.
To make it clear let me use and example, let's say I have a C program implementing a phone list, so I have contacts as "objects" (among others), I want to let my users to script the program using tcl for example having a port listening to tcl commads
foreach contact in $phonelist {
puts $contact
puts [name $contact]
}
where phonelist is a liked list of C struct Contact and contact is a Contact struct like:
struct Contact {
char *name;
char *surname;
char *phone_number;
}
The problem is how to access the data structure in tcl in a way like:
puts "$contact.name $contact.surname"
being more tclish like:
puts "[name $contact] [surname $contact]"
After a bit thinking on it , my idea is the tcl way of doing this is not giving access to the data structure but to design a set of commands to access the data and extend the interpreter with those commands, for example:
puts "[contact name $contact] [contact surname $contact] [contact phone $contact]"
or something like this.
Is this the better way to proceed to give tcl access to "objects" of the C program? this also would apply to accessing classes and objects both methods and properties.
regards
Hi,or a config file the program reads at startup. I want users to issue commands like:
I was wondering for the best way to make c and c++ data structures accesible to tcl running as a script engine for a c/c++ program.
The idea is to give scripting capabilities to a C/C++ program using tcl as a extension scripting language in a way users can control the main program using tcl. So I need to access data structures (structs, classes...) from tcl.
To make it clear let me use and example, let's say I have a C program implementing a phone list, so I have contacts as "objects" (among others), I want to let my users to script the program using tcl for example having a port listening to tcl commads
foreach contact in $phonelist {
puts $contact
puts [name $contact]
}
where phonelist is a liked list of C struct Contact and contact is a Contact struct like:
struct Contact {
char *name;
char *surname;
char *phone_number;
}
The problem is how to access the data structure in tcl in a way like:
puts "$contact.name $contact.surname"
being more tclish like:
puts "[name $contact] [surname $contact]"
After a bit thinking on it , my idea is the tcl way of doing this is not giving access to the data structure but to design a set of commands to access the data and extend the interpreter with those commands, for example:
puts "[contact name $contact] [contact surname $contact] [contact phone $contact]"
or something like this.
Is this the better way to proceed to give tcl access to "objects" of the C program? this also would apply to accessing classes and objects both methods and properties.
regards
Hi,commads or a config file the program reads at startup. I want users to issue commands like:
In my view, SWIG was build to address this exact same problem. I have
been using it for years (15+).
http://www.swig.org/
There is highly probable that it will read you c++ header files,
unmodified or with little modification, and write all the "glue" code required. It supports even STL structures...
George
ΣÏÎ¹Ï 24/3/2022 21:44, ο/η pd ÎγÏαÏε:
Hi,
I was wondering for the best way to make c and c++ data structures accesible to tcl running as a script engine for a c/c++ program.
The idea is to give scripting capabilities to a C/C++ program using tcl as a extension scripting language in a way users can control the main program using tcl. So I need to access data structures (structs, classes...) from tcl.
To make it clear let me use and example, let's say I have a C program implementing a phone list, so I have contacts as "objects" (among others), I want to let my users to script the program using tcl for example having a port listening to tcl
foreach contact in $phonelist {
puts $contact
puts [name $contact]
}
where phonelist is a liked list of C struct Contact and contact is a Contact struct like:
struct Contact {
char *name;
char *surname;
char *phone_number;
}
The problem is how to access the data structure in tcl in a way like:
puts "$contact.name $contact.surname"
being more tclish like:
puts "[name $contact] [surname $contact]"
After a bit thinking on it , my idea is the tcl way of doing this is not giving access to the data structure but to design a set of commands to access the data and extend the interpreter with those commands, for example:
puts "[contact name $contact] [contact surname $contact] [contact phone $contact]"
or something like this.
Is this the better way to proceed to give tcl access to "objects" of the C program? this also would apply to accessing classes and objects both methods and properties.
regards
The Tk paradigm is one way to do this. Define a command to obtain a phone list, lets call it [new_phonelist]:
The "new..." command, when invoked, will then register a new command, say pl341592. That command has the form: pl341592 <subcommand> ?<arguments?
On the C/C++ side, the command implementation can be a simple piece of dispatch code for a "phonelist" command that uses the clientData field to hold the actual C++ object handle. This way it can access the relevant fields or call relevant methods.
You can get more insight on this by exploring the Tk implementation for widgets, at least the command interface portion.
SWIG is pretty interesting, I was reading it and it solves the problem with elegance.style way is to define a set of commands to present a interface from tcl to the data and procedures in the C side, you can define commands and subcommands something like string does or like tk, as pointed by briang
But I was asking for the best way to design a tcl interface to a program in C/C++, one way may be the swig way, to give direct access to underneath data structures and even procudures (methods, functions...) but I feel a best way or at least more tcl
My point is even when swig way is more direct and with a full mapping with original objects, the tcl way of defining a set of commands is better in the sense it is more independet of original objects and C implementation, the goal is don't have toknow the structure of datatypes, objects and their relations to use them from tcl (I know you can also do the tcl way using swig)
For example, using the phone list example, maybe the C implemetation is a linked list of structs like:
struct Contact {
char *name;
char *phone_number;
struct Contact *next
}
the direct swig way would give a tcl:
Contact c
while {expr {[c next] ne "NULL"}} {
puts "[c name] [c phone_number]"
}
But I don't want to know of "next" procedure, an implementation detail, I only want to know about phonelist and contacts, so maybe a better way would be:
phonelist pl
foreach c in pl {
puts "[contact name $c] [contact phone_number $c]"
}
or even:
phonelist -create pl
foreach c in [phonelist contacts] {
puts "[phonelist contact name $c] [phonelist contact phone_number $c]"
}
maybe this last one is more in the line of what briang said about using the tk way.
My question is what you think is a better approach, something akin the swig direct way or something akin the tcl commands way
El jueves, 24 de marzo de 2022 a las 21:46:13 UTC+1, briang escribió:
The Tk paradigm is one way to do this. Define a command to obtain a phone list, lets call it [new_phonelist]:
The "new..." command, when invoked, will then register a new command, say pl341592. That command has the form: pl341592 <subcommand> ?<arguments?
On the C/C++ side, the command implementation can be a simple piece of dispatch code for a "phonelist" command that uses the clientData field to hold the actual C++ object handle. This way it can access the relevant fields or call relevant methods.
You can get more insight on this by exploring the Tk implementation for widgets, at least the command interface portion.
SWIG is pretty interesting, I was reading it and it solves the problem with elegance.style way is to define a set of commands to present a interface from tcl to the data and procedures in the C side, you can define commands and subcommands something like string does or like tk, as pointed by briang
But I was asking for the best way to design a tcl interface to a program in C/C++, one way may be the swig way, to give direct access to underneath data structures and even procudures (methods, functions...) but I feel a best way or at least more tcl
My point is even when swig way is more direct and with a full mapping with original objects, the tcl way of defining a set of commands is better in the sense it is more independet of original objects and C implementation, the goal is don't have to knowthe structure of datatypes, objects and their relations to use them from tcl (I know you can also do the tcl way using swig)
For example, using the phone list example, maybe the C implemetation is a linked list of structs like:
struct Contact {
char *name;
char *phone_number;
struct Contact *next
}
the direct swig way would give a tcl:
Contact c
while {expr {[c next] ne "NULL"}} {
puts "[c name] [c phone_number]"
}
But I don't want to know of "next" procedure, an implementation detail, I only want to know about phonelist and contacts, so maybe a better way would be:
phonelist pl
foreach c in pl {
puts "[contact name $c] [contact phone_number $c]"
}
or even:
phonelist -create pl
foreach c in [phonelist contacts] {
puts "[phonelist contact name $c] [phonelist contact phone_number $c]"
}
maybe this last one is more in the line of what briang said about using the tk way.
My question is what you think is a better approach, something akin the swig direct way or something akin the tcl commands way
El jueves, 24 de marzo de 2022 a las 21:46:13 UTC+1, briang escribió:
The Tk paradigm is one way to do this. Define a command to obtain a phone list, lets call it [new_phonelist]:
The "new..." command, when invoked, will then register a new command, say pl341592. That command has the form: pl341592 <subcommand> ?<arguments?
On the C/C++ side, the command implementation can be a simple piece of dispatch code for a "phonelist" command that uses the clientData field to hold the actual C++ object handle. This way it can access the relevant fields or call relevant methods.
You can get more insight on this by exploring the Tk implementation for widgets, at least the command interface portion.
iterate upon it. This may be impractical if the contact list has 500 million entries, from both a space and time aspect. Something to consider carefully when designing the interface.phonelist -create plThis style may not be what you would like to see, but you do have to consider that the call to [phonelist contacts] must first fully replicate, from start to finish, the entire list of contact info into a Tcl list before the [foreach] command can
foreach c in [phonelist contacts] {
puts "[phonelist contact name $c] [phonelist contact phone_number $c]"
}
To make it clear let me use and example, let's say I have a C program implementing a phone list, so I have contacts as "objects" (among
others), I want to let my users to script the program using tcl for
example having a port listening to tcl commads or a config file the
program reads at startup. I want users to issue commands like:
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 463 |
Nodes: | 16 (2 / 14) |
Uptime: | 157:09:58 |
Calls: | 9,384 |
Calls today: | 4 |
Files: | 13,561 |
Messages: | 6,096,000 |