Accessor function for C pointer in Swig - c

I'm attempting to build a test framework in TCL that will allow me to perform scripted tests on a remote device over a TCP socket. There already exists a Visual Basic interface and with SWIG in Ubuntu I'm reusing the C functions that it calls to build a shared library that will work as an extension to TCL.
The device is controlled via C remote procedure calls. I'm able to send complex structures to and from TCL using SWIG to wrap the functions that call these RPCs. SWIG will even give me accessor functions to allow me create pointers to these structs which I can feed into the RPC functions. However I'm stuck when I want to create a pointer to primitives, or single data elements. SWIG does not create accessor functions in this case. For example, a RPC function may have a prototype of the following form:
rpc_testDefaults ( testDefaults_t, *testDefaults, dataValid_t, *validStatus );
Here *testDefaults is a pointer to a complex structure, and SWIG generates accessor functions of the form new_testDefaults_t, delete_testDefaults_t, testDefaults_t_firstElement_set, testDefaults_t_firstElement_get etc.
*validStatus is a pointer to a single data element (uint32_t), but no accessor functions are generated.
My interface file is of the form:
// rpcTest.i
%module rpcTest
%include <stdint.h>
%{
#include "header.h"
}%
%include "header.h"
My header.h defines the types for testDefaults_t and dataValid_t.
Ideally I'd be able to include a flag or something in the SWIG interface file which would tell SWIG to treat all pointers the same as structs, from the point of view of creating accessors.
I've been able to access the data in *validStatus by either defining the typedef for dataValid_t as a single element struct, which gives me the regular accessor functions, or using cpointer.i and defining the type in the interface file, which gives me a different set of accessor functions. I would prefer to not have to go either of these routes as this problem will occur hundreds of times in the full api, which is subject to change. I've also got it to work using typemaps and assigning the pointer as an output, but again I feel this is adding tedious code and I would prefer to use the same set of accessor functions to manage this data.
So, is there a way to automate the detection of these pointers and give them accessor functions without having to write hundreds of lines of regularly redundant code?
Any help is much appreciated.

Eventually I found a solution:
%pointer_functions(dataValid_t,validStatus) generates the new_, delete_, _assign, and _value functions for the single piece of data called validStatus. I thought this was only for structures. I have to do this every time I encounter this problem but is far preferable to modifying the source.

Related

Dealing with custom types in a library using dlopen

I need to load a library dynamically at runtime, and the code doesn't have the custom types the library uses defined at compile time.
This seems to initialize the struct correctly:
void *data = malloc(128);
InitCustomType(data);
The problem with this approach is that the size of the struct is unknown.
This is an example of how the library is normally used: (CustomType is a struct)
CustomType customType;
InitCustomType(&customType);
// Now customType can be used in the library calls
This is an example of how the library is normally used: (CustomType is a struct)
If that is an example, then nothing should stop you from using CustomType, or using malloc(sizeof(CustomType)).
the code doesn't have the custom types the library uses defined at compile time.
That statement is inconsistent with above. Either you do have a definition of CustomType, or you don't. If you do, you don't have a problem. If you don't, you can't really use this library.

Is There a Standard Method for Making Abstract Data Types in ansi C?

I recently transferred into a different school & cs program. The language used is C as compared to java which was taught at my previous school. One of my main issues which may be the result of not writing enough C code is that I'm having trouble finding a standard for making Abstract Data Types.
From what I've seen, there are tons of ways these are implemented and the lack of a visible standard is making me worried I missed something while self learning C. I've seen implementations that hide the init variable from the user such as
#define createVector(vec) Vector vec; void init_vector(&vec)
and another version which is what I would be more used to in which a handle is used to hold the returned pointer to struct from the createVector() function. The issue is I can't find any detailed description on handles online or in my course 2 book. The course 2 book only shows the interface and methods but not how they are grouped together in a way that hides the implementation from the user. I wanted to know if there was a "correct" way/standard for ADTs? The book in question is Robert Sedgewick "Algorithms in C - Third Edition".
Abstract Data Types
Split your sources.
The header (.h files) contains the abstract declarations like the datatypes (structs, functions, enums, constants, etc)
The actual implementation is done in the .c files.
When using such a (lets call it) module you only include the header in your source.
The implementiation you use is decided at linking time. You may decide to use different .c files for implementation or a static library (or even a dynamic library).
If you want to hide the data you use opaque structures.
Why is this standard? Ever heard of the FILE type? This is the opaque type used for IO in c's standardlibrary. You only include the header stdio.h and leave the implementation to the compiler. The header on the other hand or at least the symbols that it defines are well documented (and part of the c standard).
Abstract Classes
Java has the concept of an abstract class. Well, it also has the concept of a class in general. C does not. This is more a personal opinion but don't waste time on emulating language features that the language does not offer.
For none abstract methods use functions which take a pointer to a (probably opaque) struct containing all the data needed as first parameter, like fprintf(FILE*,const char*,...).
For abstract methods you will need function pointers.
Use these function pointers (or maybe a struct of function pointers) like a strategy. You may define a method for registering such a strategyand delegate the normal functions to them. Take for example the atexit function, which globally (you may call it a singleton) adds a exiting-strategy.
The XY Problem
I'm having trouble finding a standard for making Abstract Data Types
Read about this and apply it to your question.
Instead of trying to force your solution to work rethink if the attempted solution is applicable to the problem. Try to get comfy with the techniques described above. This may need a bit of practice but then you can model your solution in a more c-styled way.
I just wanted to post this as I figured out the answer that would be more specific to my case however I understand that this probably doesn't apply to everyone. The thing I was looking for was the idea of "First Class ADTs" which use a handle to contain a pointer to the actual object that was created from a .c implementation file that would be hidden from the user.
For ADT using C, this approach is the standard as far as I know. You will have a header (.h) file and one or more implementation (.c) files. The header file might look something like:
typedef struct * Doodad;
Doodad * doodadInit(int);
void doodadDestroy(Doodad *);
int doodadGetData(Doodad *);
void doodadSetData(int);
For your implementation file(s) you might have:
typedef struct iDoodad {
int data;
} Doodad;
Doodad * doodadInit(int data) {
...
}
...

alternative to defining struct in header file for 'error dereferencing pointer to incomplete type' in c

I am aware that there are other questions about this which usually point to the standard solution of having both the struct and typedef struct declared and defined in the header file. However, I am looking at someone's else code which hasin the header:
struct A;
typedef struct A A_t;
Then the struct A is defined in *.c file together with the implementation of other functions. The implementation of A includes many defines, etc that are as well included in *.c not in the header.
Then in main.c the header is included and I have declared and defined new functions making use of (null) pointers to A_t which gives error dereferencing pointer to incomplete type when trying to access to a member of the struct.
Is there an alternative to declare and define the struct and typedef into the header for this case?
EDIT: Just to clarify that the original code foresees that the user creates some functions which are then passed to the main routines. For instance the user is supposed to create a function to connect to a socket, close a socket connection, transmit and receive data. Since I need an identifier/filedescriptor for the socket I have added an int to A's definition which is what I can't dereference. I hope this clarifies the context.
If someone has coded it like this and you assume that someone is a decent enough programmer, he might have done this on purpose.
In a proper C API design, you might have the need to expose a pointer to an internal data structure in order to be able to store context over function calls and expect your library user to receive that pointer from you, store it and hand it back with the next call into your library.
In this case, the most simple answer is: You are not expected to mess with this pointer, and you are not expected to allocate one of those structures yourselves nor dereference a pointer to it. X11 is a famous example of doing that.
If you actually need to be able to dereference such a pointer or access structure members, you need access to the full structure definition in some header file. Your choice where you want to put the definition, you can have more than one (i.e. there is no such thing as "the" header file) header.
Following your edit, I would propose you do it like so:
Apparently, the creator of your library has taken a lot of care to not expose the structure outside his module - I would leave it like that.
You need to add an int to the structure and have done so, so you obviously have access to the .c source. Do that, put it into the C file and leave the structure definition there. Add a setInt(struct A*, int) and a getInt(struct A*) function that allows you to set and retrieve the int from such an opaque pointer (getter and setter functions). Expose those 2 functions in the header of the C file. This leaves the original intention of the information hiding intact but still allows you to extend the structure.
You have two basic options:
Define the structure and all its members in a header file to be included in all the .c files that use this structure.
Leave the definition of the structure in a specific .c file which will also include the definitions of all the functions that access its members and those functions could be declared in a header file to be included in other .c files that need to manipulate the structure. Of course, you will still be able to use pointers to this structure in other .c files but you will not be able to access its members. This method may be viewed as is one of C's ways of providing sort of encapsulation or information hiding.

Passing pointers to structures into C functions from TCL using SWIG

I'm attempting to build a test framework in TCL that will allow me to perform scripted tests on a remote device over a TCP socket. There already exists a Visual Basic interface and with SWIG in Ubuntu I'm reusing the C functions that it calls to build a shared library that will work as an extension to TCL. I have had success at incorporating basic functions, such as opening/closing sockets, and basic read/writes to single memory addresses on the device using SWIG's typemaps.i to provide pointers (*OUTPUT) to the readAddress function to return address values to TCL.
The problem is that for this to be useful I am going to have to incorporate a large number of Remote Procedure Calls which pass complicated data types into (and back out of!) the device. As a proof of concept I'm attempting to get a relatively simple function working. This attempts to read default test parameters via an RPC; a pointer to a struct is provided for the function to use for the results: rpc_testDefaults ( testDefaults_t *testDefaults ).
The typedef for testDefaults_t is in testDefaults.h, which is in the style of the following:
// testDefaults.h
#include <stdint.h>
typedef uint32_t customType_t;
typedef struct
{
customType_t varName1; // Description
uint32_t varName2; // Description
// 13 more uint32_t elements
} testDefaults_t;
// Two more struct type definitions
testDefaults.c is along the lines of this:
// testDefaults.c
#include "testDefaults.h"
// #ifdefs to compile as 'client' OR 'server' (defaults to 'client')
rpc_testDefaults ( testDefaults_t, *testDefaults )
{
// function
}
My SWIG interface file looks like this:
// rpcTest.i
%module rpcTest
%include <cpointer.i>
%include "testDefaults.h"
%pointer_functions(testDefaults_t, testDefaults);
//%apply int *OUTPUT {testDefaults_t, *testDefaults};
%{
#include "testDefaults.h"
extern int rpc_testDefaults ( testDefaults_t, *testDefaults )
}%
extern int rpc_testDefaults ( testDefaults_t, *testDefaults )
There are many other .c and header files in the same folder which support this function and the others which I mentioned I got working.
I run swig -tcl -debug-typedef rpcTest.i which gives me rpcTest_wrap.c, I can see that the testDefaults_t has been recognised as a type/scope as is has a section in the debug output (it's also included in the unnamed scope section: testDefaults_t -> testDefaults_t).
I run gcc -fPIC -DCLIENT_FLAG -c *.c -I/usr/include/tcl8.5 and I get an error from a line in the SWIG output file: rpcTest_wrap.c:1803:3: error: unknown type name 'testDefaults_t' (plus a lot more errors derived from this). The line in question is the first line in this function:
static testDefaults_t *new_testDefaults() {
return (testDefaults_t *)malloc(sizeof(testDefaults_t));
}
Which I believe is cpointers.i creating a function for TCL to 'create' a pointer to that struct.
I have a feeling this is something to do with gcc including files in the wrong order, but I'm at a loss as to what to do next. I've tried many combinations of defining the header in various places in the interface file and this is the combination that gives the least errors :). You can see my commented-out partial attempt at using typemaps instead of cpointers but I'm even more clueless with these, I managed it for a pointer to a single value but it didn't seem to be working for a struct with it's own type. It did compile without error though.
So is it possible to get what I'm trying to achieve working using cpointers.i? Any suggestions on how to overcome the compiler issue? Would I be better off learning how to use typemaps? Let me know where I can provide more detail if it would help, I may be leaving out crucial information as I've had to summarize and change all the names as this is company stuff.
Any help/criticism would be greatly appreciated!
Looking into the rpcTest_wrap.c file I noticed that the include for testDefaults.h was right after the group of functions that were attempting to use it. I replaced "int" in the interface file with testDefaults_t (I think this is correct), ran SWIG, edited the output (dangerous I know!) so that the include happened just before these functions, and it compiles fine. I can load the shared library into TCL and run the new functions.
However, and this is perhaps a new question, [in TCL] using the new functions to create a pointer, feed it into rpc_testDefaults, and attempting to dereference the resulting pointer using testDefaults_value just returns another pointer. I realize that I can't just dereference a struct, but I have no idea how to dereference individual elements. Any tutorials I can find only refer to dereferencing non-structs (and none of these tutorials are for TCL). Something somewhere mentioned that there are similarities between structs and TK widgets so I'll have a look into this, but I'm still not sure is what I'm attempting to do even possible, and if it is is this the right way to do it.
Again, what I am attempting to do is in TCL, access individual elements of a struct which has been returned from (or fed into) a C function via a pointer.
UPDATE: I got this working in the end by using the functions SWIG generates which I discovered in the end of the wrapper file. cpointer.i wasn't needed at all. In TCL I first create a pointer using the new function new_testDefaults which returns a string with in the form of a TCL style pointer. I pass this pointer into rpc_testDefaults, which returns nothing as it was actually a void function. I can then access individual elements from the struct referenced by the above pointer by setting it as an argument to the elementName_get and elementName_set functions generated by SWIG. The next task is to get more complicated functions working, structs in structs etc, but now that I'm familiar with the methodology it shouldn't be too hard.

Is it possible to avoid global variables in a strictly procedural program?

Being a developer born and raised on OO, I was curious to hear how it's possible to avoid global state in a procedural program.
You can also write object-oriented code in C. You don't get all the C++ goodies and it's ugly, and you have to manually pass the this pointer (I've seen self used for this, in order to make it compatible with C++), but it works. So technically, you don't need global state in pure procedural languages for the very same reasons you don't need it in object-oriented languages. You just have to pass the state around explicitly, rather than implicitly like in OO languages.
As an example, look at how the file I/O functions in the C standard library work with pointer to FILE objects that are (largely) opaque. Or look at how OS APIs deal with handles and such to encapsulate information. A program creates objects, uses APIs that act on those objects and closes/deletes the objects - all using straight C.
A global variable is nothing but an implicit procedure argument. Make it explicit and the global variable goes away.
Note: the fact that you no longer use a global variable does not mean that you no longer use global state! What we did above was just a purely syntactical transformation, the semantics of the program haven't changed at all. It's just as non-composable, non-modular, non-threadsafe, non-parallelizable as it was before.
All OO is a mindset and a whole bunch of compiler support.
You can achieve much the same by discipline, coding conventions, and passing around structures in most languages.
For example I used to have functions/procedures prefixed with their module identity, taking the first parameter as being the related module struct.
// System.h
typedef struct _System
{
struct _System *owner;
LinkedList *elements;
} System;
// System.c
int System_FindName ( System * system, char *name)
{
..
}
etc..
I'd really seriously not like to have to go back to coding like this though. I'm very happy that I haven't had to write and debug a linked list for at least 18 years. It was hard back then without the internet and sitting there isolated in the corner of a cold brightly lit room with green phosphors burning into your retina...
Of course. Just declare a struct somewhere, allocate some memory for it, pass the pointer to the allocated memory to an initialization function, and off you go. Just pass the pointer to all the functions that require using the struct.
Though the question arises as to where you store the pointer to the data you don't want to be global, and then you may end up with a global pointer ;-)
You can have variables on stack or in heap that will exist during all the program life.
Passing object style structure pointers to every function is a good way to have OO C coding style.
(I would suggest to have a look in linux sources)
You could try, as an example, create with dia (the diagramming tool), a simple class (for example, a square).
http://projects.gnome.org/dia/
http://dia-installer.de/index_en.html
Then, you can transform that class in C code using dia2code:
http://dia2code.sourceforge.net/
Specifically, say you created the class square inside the square.dia diagram. Then, you type:
$ dia2code -t c square.dia
... and you will see that it is possible to convert any object-oriented programming in a C program without global variables. Explore the created files square.c and square.h
NOTE: in Windows, you'll need a workaround in order to make dia2code work. Before using dia2code, change square.dia to square.zip, unzip it, and rename the result as square.dia
Simple. Whenever a procedure accesses a global variable, then give this variable as an argument to the procedure instead, either by value or by reference or by pointer, or by whatever your programming language provides. After that there is no more need for the variable to be global.

Resources