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.
Related
In my case I am writing a simple plugin system in C using dlfcn.h (linux). The plugins are compiled separately from the main program and result in a bunch of .so files.
There are certain functions that must be defined in the plugin in order for the the plugin to be called properly by the main program. Ideally I would like each plugin to have included in it a .h file or something that somehow states what functions a valid plugin must have, if these functions are not defined in the plugin I would like the plugin to fail compilation.
I don't think you can enforce that a function be defined at compile time. However, if you use gcc toolchain, you can use the --undefined flag when linking to enforce that a symbol be defined.
ld --undefined foo
will treat foo as though it is an undefined symbol that must be defined for the linker to succeed.
You cannot do that.
It's common practice, to only define two exported functions in a library opened by dlopen(), one to import functions in your plugin and one to export functions of your plugin.
A few lines of code are better than any explanation:
struct plugin_import {
void (*draw)(float);
void (*update)(float);
};
struct plugin_export {
int (*get_version)(void);
void (*set_version)(int);
};
extern void import(struct plugin_import *);
extern void export(struct plugin_export *);
int setup(void)
{
struct plugin_export out = {0};
struct plugin_import in;
/* give the plugin our function pointers */
in.draw = &draw, in.update = &update;
import(&in);
/* get our functions out of the plugin */
export(&out);
/* verify that all functions are defined */
if (out.get_version == NULL || out.set_version == NULL)
return 1;
return 0;
}
This is very similar to the system Quake 2 used. You can look at the source here.
With the only difference, Quake 2 only exported a single function, which im- and exports the functions defined by the dynamic library at once.
Well after doing some research and asking a few people that I know of on IRC I have found the following solution:
Since I am using gcc I am able to use a linker script.
linker.script:
ASSERT(DEFINED(funcA), "must define funcA" ) ;
ASSERT(DEFINED(funcB), "must define funcB" ) ;
If either of those functions are not defined, then a custom error message will be output when the program tries to link.
(more info on linker script syntax can be found here: http://www.math.utah.edu/docs/info/ld_3.html)
When compiling simply add the linker script file after the source file:
gcc -o test main.c linker.script
Another possibility:
Something that I didn't think of (seems a bit obvious now) that was brought to my attention is you can create small program that loads your plugin and checks to see that you have valid function pointers to all of the functions that you want your plugin to have. Then incorporate this into your build system, be it a makefile or a script or whatever. This has the benefit that you are no longer limited to using a particular compiler to make this work. As well as you can do some more sophisticated checks for other other things. The only downside being you have a little more work to do to get it set up.
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.
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.
I'm a beginner to C, but I've had a bit of experience with some other programing languages like Ruby and Python. I would very much like to create some of my own functions in C that I could use in any of my programs that just make life easier, however I'm a little bit confused about how to do this.
From what I understand the first part of this process is to create a header file that contains all of your prototypes, and I understand that, however from what I understand it is frowned upon to include anything other than declarations in your header files, so would you also need to create a .c file that contained the actual code and then #include that in all your programs along with the header file? But if so, why would you need a header file in the first place, since defining a function also declares it?
Finally, what should you put in the main() function of your header file? Do you just leave it blank, or do you not include it?
Thanks!
The declaration of a function lets the compiler know that at link time such a function will be available. The definition of the function provides that implementation, and additionally it also serves as the declaration. There is no harm in having multiple declarations, but only one implementation can be provided. Also, at least one declaration (or the only implementation) must come before any use of the function - this alone makes forward declarations necessary in cases where two functions call one another (both cannot be before the other).
So, if you have the implementation:
int foo(int a, int b) {
return a * b;
}
The corresponding declaration is simply:
int foo(int a, int b);
(The argument names do not matter in the declaration, i.e., they can be omitted or different than in the implementation. In fact you could declare only int foo(); and it would work for the above function, but this is mainly a legacy thing and not recommended. Note that to declare a function that takes no arguments, put void in the argument list, e.g., int bar(void);)
There are a number of reasons why you would want to have separate headers with only the declaration:
The implementation may be in a separate file, which allows for organisation of code into manageable pieces, and may be compiled by itself and need not be recompiled unless that file has changed - in large projects where the total compilation time can be an hour it would be absurd to re-compile everything for a small change.
The implementation source may not be available, e.g., in case of a closed-source proprietary library.
The implementation may be in a different language with a compatible calling convention.
For practical details on how to write code in multiple files and how to use libraries, please consult a book or tutorial on C programming. As for main, you need not declare it in a header unless you are specifically calling main from another function - the convention of C programs is to call main as int main(int, char**) at start of the execution.
When compiling, each .c-file (or .cpp-file) will be compiled to an own binary first.
If one binary file is using functions from another,
it just knows "there is something outside named xyz" at that time.
Then the linker will put them together in one file and rewrite the parts of each file
which are using functions of other files,
so that they actually know where to find the used functions.
What will happen if you put code in a .h file:
At compilation time, each included h-file in a c-file will be integrated in the c-file.
If you have code for xyz in a h-file and you´re including it in more thana one c-file,
each of this compiled c-files will have a xyz. Then, the linker will be confused...
So, function code have to be in a own c file.
Why use a h-file at all?
Because, if you call xyz in your code, how should the compiler know
if this is a function of another c-file (and which parameters...)
or an error because xyz does not exist?
The reason for header files in c are for when you need the same code in multiple scripts. So if you are just repeated the same code in one script then yes it would be easier to just use a function. Also for header files, yes you would need to include a .c file for all the computations.
I have an interface with which I want to be able to statically link modules. For example, I want to be able to call all functions (albeit in seperate files) called FOO or that match a certain prototype, ultimately make a call into a function in the file without a header in the other files. Dont say that it is impossible since I found a hack that can do it, but I want a non hacked method. (The hack is to use nm to get functions and their prototypes then I can dynamically call the function). Also, I know you can do this with dynamic linking, however, I want to statically link the files. Any ideas?
Put a table of all functions into each translation unit:
struct functions MOD1FUNCS[]={
{"FOO", foo},
{"BAR", bar},
{0, 0}
};
Then put a table into the main program listing all these tables:
struct functions* ALLFUNCS[]={
MOD1FUNCS,
MOD2FUNCS,
0
};
Then, at run time, search through the tables, and lookup the corresponding function pointer.
This is somewhat common in writing test code. e.g., you want to call all functions that start with test_. So you have a shell script that grep's through all your .C files and pulls out the function names that match test_.*. Then that script generates a test.c file that contains a function that calls all the test functions.
e.g., generated program would look like:
int main() {
initTestCode();
testA();
testB();
testC();
}
Another way to do it would be to use some linker tricks. This is what the Linux kernel does for its initialization. Functions that are init code are marked with the qualifier __init. This is defined in linux/init.h as follows:
#define __init __section(.init.text) __cold notrace
This causes the linker to put that function in the section .init.text. The kernel will reclaim memory from that section after the system boots.
For calling the functions, each module will declare an initcall function with some other macros core_initcall(func), arch_initcall(func), et cetera (also defined in linux/init.h). These macros put a pointer to the function into a linker section called .initcall.
At boot-time, the kernel will "walk" through the .initcall section calling all of the pointers there. The code that walks through looks like this:
extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
static void __init do_initcalls(void)
{
initcall_t *fn;
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_one_initcall(*fn);
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_work();
}
The symbols __initcall_start, __initcall_end, etc. get defined in the linker script.
In general, the Linux kernel does some of the cleverest tricks with the GCC pre-processor, compiler and linker that are possible. It's always been a great reference for C tricks.
You really need static linking and, at the same time, to select all matching functions at runtime, right? Because the latter is a typical case for dynamic linking, i'd say.
You obviusly need some mechanism to register the available functions. Dynamic linking would provide just this.
I really don't think you can do it. C isn't exactly capable of late-binding or the sort of introspection you seem to be requiring.
Although I don't really understand your question. Do you want the features of dynamically linked libraries while statically linking? Because that doesn't make sense to me... to static link, you need to already have the binary in hand, which would make dynamic loading of functions a waste of time, even if you could easily do it.