error C2099: initializer is not a constant - c

Protocol.h
typedef struct sDevice_d
{
char name[24];
signed int (*Send)(unsigned char*, unsigned short);
signed int (*Recv)(unsigned char*, unsigned short);
} sDevice_d, *psDevice_d;
Device.c
#include "Protocol.h"
sDevice_d sDevice = { "ten", I2c_Send };
psDevice_d psDevice = &sDevice;
static signed int I2c_Send(unsigned char* buf, unsigned short len)
{
return 0;
}
In the code above I am getting the following Error:
error C2099: initializer is not a constant
Please help me in resolving this.
I am using Visual studio Win32 application.

The function I2c_Send needs to be defined and visible
before attempting to create and initializing a struct using
it in its initializer list. I have included an adaptation of your code
below that illustrates this in two files:
protocol.h
typedef struct
{
char name[24];
signed int (*Send)(unsigned char*, unsigned short);
signed int (*Recv)(unsigned char*, unsigned short);
} S_DEVICE;
//prototype here
static signed int I2c_Send(unsigned char* buf, unsigned short len);
device.c
#include "protcol.h"
S_DEVICE sDevice_d = {"ten", I2c_Send, I2c_Send};
int main(void)
{
return 0;
}
//define here
static signed int I2c_Send(unsigned char* buf, unsigned short len)
{
return 0;
}
This source compiled and built using an ANCI C compiler (using C99 extensions) and should yield
similar results in your Visual Studios, Win32 environment.

Related

How to pass Char array back

I'm writing a code to decode a specific, all function seem to be working fine with correct decoding result but I'm struggling to get the data into tydef struct
I'm define var like this
typedef struct{
unsigned char utctime[8];
unsigned char Lat[11];
unsigned char LatDirect;
unsigned char Status;
unsigned char Long[11];
unsigned char LongDirect;
//unsigned float speed;
unsigned char date[6];
}StrGPSDATA;
unsigned char datatestRealword1[100] = " *** TEST DATA HERE *** ";
Here is pseudo code.
unsigned char parseByDelimiter(char *inputData, const char delims, int index, unsigned int maxIndexSize){
unsigned char valOut[maxDataOut] = {0};
// Parse/Split value //
return valOut; // Debugging show correct result
}
void RMCDecode(unsigned char *dataIn, unsigned int sizeIn){
unsigned char dataExt[60] = {0};
// do something to get value to //
parseByDelimiter(dataExt, ',', 1, 60); // Send decoded value to parse
}
void main(void){
RMCDecode(datatestRealword1, 100);
}
A debugger report a correct value
But after when I tried
GPSDATARMC.utctime = parseByDelimiter(RMC_DATA, ',', 0, 10);
I gave an error incompatible data type, I don't know how to write value into my typedef. Anyone got an idea?
Thank you

error: redefinition of ‘struct rsa_meth_st’

I'm trying to develop an RSA engine. My engine was somewhat working until I try to integrate my engine with an apache httpd server. After installing the httpd from the source code, it turns out that, I can't compile my engine code anymore. I get the following error while I try to compile (it was compiling before and I did not make any changes to my engine code).
$gcc -fPIC -c r_engine.c
r_engine.c:29:8: error: redefinition of ‘struct rsa_meth_st’
struct rsa_meth_st {
^
In file included from /usr/include/openssl/crypto.h:131:0,
from r_engine.c:7:
/usr/include/openssl/ossl_typ.h:147:16: note: originally defined here
typedef struct rsa_meth_st RSA_METHOD;
My sample source code is like the following,
#include <openssl/opensslconf.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/engine.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/ossl_typ.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
/* Declared in ossl_typ.h */
/* typedef struct rsa_meth_st RSA_METHOD; */
//#ifndef INCLUDE_OSSL_TYP_H
//#define INCLUDE_OSSL_TYP_H
struct rsa_meth_st {
const char *name;
int (*rsa_pub_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_pub_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
int (*init) (RSA *rsa);
int (*finish) (RSA *rsa);
int flags;
char *app_data;
int (*rsa_sign) (int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
int (*rsa_verify) (int dtype, const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
};
//#endif
static int eng_rsa_pub_enc (int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding){
printf ("Engine is encrypting using pub key \n");
}
static int eng_rsa_pub_dec (int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding){
printf ("Engine is decrypting using pub key \n");
}
static int eng_rsa_priv_enc (int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding __attribute__ ((unused))){
printf ("Engine is encrypting using priv key \n");
}
static int eng_rsa_priv_dec (int flen, unsigned char *from, unsigned char *to, RSA * rsa, int padding __attribute__ ((unused))){
printf ("Engine is decrypting using priv key \n");
}
/* Constants used when creating the ENGINE */
static const char *engine_rsa_id = "r_engine";
static const char *engine_rsa_name = "Demo engine";
struct rsa_meth_st new_rsa =
{
"demo RSA Engine",
eng_rsa_pub_enc,
eng_rsa_pub_dec,
eng_rsa_priv_enc,
eng_rsa_priv_dec,
NULL,
NULL,
NULL,
NULL,
RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
NULL,
NULL,
NULL,
NULL
};
static int bind (ENGINE * e, const char *id){
printf ("%s\n", id);
if (!ENGINE_set_id (e, engine_rsa_id) ||
!ENGINE_set_name (e, engine_rsa_name) ||
!ENGINE_set_RSA (e, &new_rsa))
return 0;
return 1;
}
IMPLEMENT_DYNAMIC_BIND_FN (bind)
IMPLEMENT_DYNAMIC_CHECK_FN ()
I notice that, with a fresh version of OS, my code compiles and runs well.
I understand that struct rsa_meth_st was defined in ossl_typ.h file, but that did not throw any error previously but why now?
My gcc version is gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
This seems like a case where you have been building with two different branches of OpenSSL. Between the 1.0.2 and the 1.1.1 branches, quite a few types were made opaque. This means that certain structure definitions that were publicly visible in 1.0.2 are private in 1.1.1. Your struct rsa_meth_st is one of them. Therefore your code compiles with 1.1.1 but not with 1.0.2.
The solution to your problem depends on which OpenSSL version you want to use. In either case, you have to remove the entire struct rsa_meth_st definition from your code. If you intend to build with 1.0.2 (which is now out of support), then its definition is known already and exposed via the header files so you don't need to repeat it yourself. If you intend to build with 1.1.1, you have to use RSA_meth_new() followed by the appropriate RSA_meth_set_() functions.
In general, when you see constructs like typedef struct rsa_meth_st RSA_METHOD you are typically not supposed to define that same struct yourself because it is already defined somewhere else (visibly or hidden). Instead, you should refer to that type via RSA_METHOD or, more likely, RSA_METHOD *.

Is it possible to access the different Structure with same members by using Macros or any other functionality at runtime?(Structure updated))

In this code contains two structures and their naming is different. Structure member naming is same but type is different. Is there any possibility to change the structure name at run time by using macros or other functionality.
typedef struct STag_ABCRegisters
{
unsigned long aaa;
unsigned long bbb;
unsigned long ccc;
unsigned long dddd;
}RegistersABC;
typedef struct STag_CDERegisters
{
unsigned short aaa;
unsigned short bbb;
unsigned short ccc;
unsigned short dddd;
}RegistersCDE;
main()
{
int type = 1;
if(type == 1)
{
RegistersABC->ccc = 10;
}
else
{
RegistersCDE->ccc = 10;
}
/* after some process again checking the type updating structure*/
type = 2;
if(type == 1)
{
RegistersABC->aaa = 10;
}
else
{
RegistersCDE->aaa = 10;
}
}
I need the help for following process
In the above code contains complexity of if else condition.
So is there any possibilities for select the structure at run time??.
See the below Pseudo code steps for your understanding
main()
{
char type = "ABC";
Registers//type//->aaa = 10; // Type of structure name should be replaced here
}
As I stated in my comment, structures are just the way memory is organized on the machine.
If both structures were compiled by the same compiler on the same machine (architecture / OS), their memory footprint will be the same and you can simply cast their pointer to one to a pointer of the other.
This, however, is not the best way to go about "inheritance" with C.
At the moment, you can have something like this:
struct STag_ABCRegisters
{
unsigned short aaa;
unsigned long bbb;
unsigned short ccc;
unsigned short dddd;
} RegistersABC;
struct STag_CDERegisters
{
unsigned short aaa;
unsigned long bbb;
unsigned short ccc;
unsigned short dddd;
} RegistersCDE;
main()
{
(struct STag_CDERegisters*) pdata = (struct STag_CDERegisters*)&RegistersABC;
data->ccc = 10;
data->aaa = 10;
}
It works, but it isn't beautiful.
If you need two of the same, the correct way would be:
struct STag_Registers
{
unsigned short aaa;
unsigned long bbb;
unsigned short ccc;
unsigned short dddd;
};
struct STag_Registers RegistersABC, RegistersCDE;
main()
{
struct STag_Registers * data = &RegistersABC;
data->ccc = 10;
data->aaa = 10;
}
If you need struct inheritance, then the "trick" is to have the "parent" placed at the head of the struct, so that the memory footprint is aligned.
struct STag_Registers
{
unsigned short aaa;
unsigned long bbb;
unsigned short ccc;
unsigned short dddd;
};
struct STag_RegistersExtended
{
struct STag_Registers parent;
// ... more types
};
This allows a pointer to struct STag_RegistersExtended to be cast as a pointer to struct STag_Registers, so that functions that accept a pointer to struct STag_Registers can also accept a pointer to struct STag_RegistersExtended.
Good luck with C.
EDIT (answering comment)
If you're writing for an embedded system and you have reserved (fixed) memory addresses for the data, you could go with something such as:
typedef struct {
unsigned short aaa;
unsigned long bbb;
unsigned short ccc;
unsigned short dddd;
} register_s;
#define PTR2REG(p) ((register_s *)(p))
#define REG_A PTR2REG(0x1000))
#define REG_B PTR2REG(0x9000))
inline void perform_work(register_s * reg)
{
reg->ccc = 10;
// ...
reg->aaa = 10;
}
main()
{
perform_work(REG_A);
perform_work(REG_B);
if(REG_A->aaa == 10) // should be true
printf("work was performed");
}
You should note that struct have a memory alignment and packing order. The compiler will add padding to the struct you defined in the question, due to the long's memory alignment requirements. You can read more about struct packing here.
If your embedded system requires an exact bit / byte match (and is free from padding requirements), you should tell the complier not to add any padding. This is often done using #pragma pack
EDIT 2
I'm not sure where the type in your question is derived from... but if you have a global variable with the address for the struct, you could go with:
typedef struct {
unsigned short aaa;
unsigned long bbb;
unsigned short ccc;
unsigned short dddd;
} register_s;
#define PTR2REG(p) ((register_s *)(p))
#define REG_A PTR2REG(0x1000))
#define REG_B PTR2REG(0x9000))
register_s * active_register = REG_A;
inline void perform_work(void)
{
active_register->ccc = 10;
// ... active_register might change
active_register->aaa = 10;
}
main()
{
perform_work();
}
This is from a C++ perspective, you really should be more careful with those language tags if this is not what you want
Since C++ does not have reflection, it's not possible to do what you want at runtime. There are workarounds though.
For example one workaround could be to have a common base-class for the common elements (which in your simple example seems to be all). The you could have an unordered map translating strings to pointers to your structure.
Example:
struct CommonBase
{
unsigned short aaa;
unsigned long bbb;
unsigned short ccc;
unsigned short dddd;
};
struct ABC : CommonBase {};
struct DEF : CommonBase {};
int main()
{
std::unordered_map<std::string, std::unique_ptr<CommonBase>> items = {
{ "ABC", new ABC },
{ "DEF", new DEF }
};
std::cout << "Select item to modify (ABC or DEF): ";
std::string input;
std::cin >> input;
items[input]->aaa = 12;
}
For members that are not common, that are unique for each respective structure, then you need to actually check like you do now and then downcast the pointer to the correct type.
For a C solution there is none really, except to manually check like you do now.
Dynamic languages like python have buildin metadata table for reflection, so we just build one for help. Now it looks much like a script language.
_Generic need C11 std to work.
some code copied from How to save the result of typeof?
// some code copied from https://stackoverflow.com/questions/42222379/how-to-save-the-result-of-typeof
// gcc -std=c11 typeid_of_test.c
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
typedef struct STRU
{
int32_t aaa;
double bbb;
int ccc;
char dddd;
}STRU;
typedef struct Metainfo
{
int type;
char* name; //or hash
int offset;
}Metainfo;
enum {TYPE_UNKNOWN, TYPE_INT, TYPE_CHAR, TYPE_DOUBLE};
#define typeid_of(T) _Generic((T), int: TYPE_INT, long: TYPE_INT, char: TYPE_CHAR, double: TYPE_DOUBLE, default: 0)
#define META(ST_, M_) {typeid_of((__typeof__(((ST_ *)0)->M_))0), #ST_ "." #M_, offsetof(ST_, M_)}
/* { typeid, name, offset } */
Metainfo meta[]={
META(STRU, aaa),
META(STRU, bbb),
META(STRU, ccc),
META(STRU, dddd),
};
int set_by_name(char* member_name, char* value, void* p)
{
int offset=0, type=0;
for(int i=0; i<sizeof(meta)/sizeof(Metainfo); i++)
if(stricmp(member_name, meta[i].name)==0)
{
offset=meta[i].offset;
type = meta[i].type;
}
switch(type)
{
case TYPE_INT:
*(int*)((char*)p+offset) = atoi(value);
break;
case TYPE_CHAR:
*(char*)((char*)p+offset) = atoi(value);
break;
case TYPE_DOUBLE:
*(double*)((char*)p+offset) = atof(value);
break;
default:
return 0;
}
return 1;
}
int main(void)
{
for(int i=0; i<sizeof(meta)/sizeof(Metainfo); i++)
printf("type:%d, name: %s, offset: %d\n", meta[i].type, meta[i].name, meta[i].offset);
STRU b={0};
set_by_name("stru.bbb", "3.1415926", &b);
printf("stru.bbb == %f", b.bbb);
return 0;
}

C (void *) used as polymorphic function pointer

I'm trying to create a system call handler, and I'm not sure how to store it.
I'm using the following typedef to store a (void *) pointer, which should receive the address of the function and an integer arg_no representing the number of arguments. Then, I create an array of this type.
typedef struct
{
void *foo;
int arg_no;
}td_sys_call_handler;
td_sys_call_handler ish[SYSCALL_HANDLER_NUM];
I'm trying to initialize the array in the following manner.
ish[0].foo = void (*halt) (void); ish[0].arg_no = 0;
ish[1].foo = void (*exit) (int status) NO_RETURN; ish[1].arg_no = 1;
ish[2].foo = pid_t (*exec) (const char *file); ish[2].arg_no = 1;
ish[3].foo = int (*wait) (pid_t); ish[3].arg_no = 1;
ish[4].foo = bool (*create) (const char *file, unsigned initial_size);
ish[4].arg_no = 2;
ish[5].foo = bool (*remove) (const char *file); ish[5].arg_no = 1;
ish[6].foo = int (*open) (const char *file); ish[6].arg_no = 1;
ish[7].foo = int (*filesize) (int fd); ish[7].arg_no = 1;
ish[8].foo = int (*read) (int fd, void *buffer, unsigned length);
ish[8].arg_no = 3;
ish[9].foo = int (*write) (int fd, const void *buffer, unsigned length);
ish[9].arg_no = 3;
ish[10].foo = void (*seek) (int fd, unsigned position);
ish[10].arg_no = 2;
ish[11].foo = unsigned (*tell) (int fd); ish[11].arg_no = 1;
But all the assignments from the function pointer to the void pointer produce the following error:
../../userprog/syscall.c: In function ‘syscall_init’:
../../userprog/syscall.c:76:17: error: expected expression before ‘void’
../../userprog/syscall.c:77:17: error: expected expression before ‘void’
../../userprog/syscall.c:78:17: error: expected expression before ‘pid_t’
../../userprog/syscall.c:79:17: error: expected expression before ‘int’
../../userprog/syscall.c:80:17: error: expected expression before ‘_Bool’
../../userprog/syscall.c:82:17: error: expected expression before ‘_Bool’
../../userprog/syscall.c:83:17: error: expected expression before ‘int’
../../userprog/syscall.c:84:17: error: expected expression before ‘int’
../../userprog/syscall.c:85:17: error: expected expression before ‘int’
../../userprog/syscall.c:87:17: error: expected expression before ‘int’
../../userprog/syscall.c:89:17: error: expected expression before ‘void’
../../userprog/syscall.c:91:17: error: expected expression before ‘unsigned’
I was under the impression that void* is the only instance of polymorphism in the language and that it can point to anything.
However, it appears that I'm wrong.
So which is the type of the pointer which can store the address of any function type?
Also, can you give me a good reference about C polymorphism? I've looked in many books but as far as I've seen the polymorphism chapter is very thin.
Thank you.
Yes, you are wrong.
void * pointers can point at any kind of data, but in C code (functions) are not data.
It's not valid to even cast between void * and function pointers: even though on most contemporary computers it will work as expected, the language does not guarantee that.
I don't understand from your code how you intended the "overloading" to be used in practice, how do you expect to call through the foo pointer? Just having the expected number of arguments is not enough, arguments have types and thus are handled differently in the function call.
The notation you need casts the system call function pointer to void *:
ish[0].foo = (void *)halt;
The C standard does not guarantee that pointers to functions will fit into pointers to data such as void *; fortunately for you, POSIX steps in and does guarantee that pointers to functions are the same size as pointers to data.
Your syntax is wrong. You should declare your function pointer first. Then you can use the address of the function pointer to assign to the pointer.
void (*halt) (void) = halt_sys_call_function;
ish[0].foo = &halt; ish[0].arg_no = 0;
C doesn't support traditional inheritance relationships in a direct way, but it does guarantee that the address of a structure is also the address of the first member of the structure. This can be used to emulate polymorphism in C. I described a similar approach in an answer I wrote about dynamic dispatch in C.
Consider a struct formatted to hold each function specifically:
typedef struct
{
void (*halt) (void);
void (*exit) (int status);
pid_t (*exec) (const char *file);
int (*wait) (pid_t);
bool (*create) (const char *file, unsigned initial_size);
bool (*remove) (const char *file);
int (*open) (const char *file);
int (*filesize) (int fd);
int (*read) (int fd, void *buffer, unsigned length);
int (*write) (int fd, const void *buffer, unsigned length);
void (*seek) (int fd, unsigned position);
unsigned (*tell) (int fd);
} myFuncs;
OR
This is messy and VERY unmaintable, but if you did cast each pointer to a void*, using void *addressOfWait = (void*)&wait;, then you could re-cast to the correct function pointer type before calling:
int (*waitFunctionPointer)(pid_t) = addressOfWait;
Then you could call that pointer:
waitFunctionPointer((pid_t) 1111); //wait for process with pid of 1111
I'll ask for #problemPotato's forgiveness for filching his structure definition:
typedef struct
{
void (*halt) (void);
void (*exit) (int status);
pid_t (*exec) (const char *file);
int (*wait) (pid_t);
bool (*create) (const char *file, unsigned initial_size);
bool (*remove) (const char *file);
int (*open) (const char *file);
int (*filesize) (int fd);
int (*read) (int fd, void *buffer, unsigned length);
int (*write) (int fd, const void *buffer, unsigned length);
void (*seek) (int fd, unsigned position);
unsigned (*tell) (int fd);
} fs_ops;
Say you have matching functions, declared like:
int ext5_open(const char * file);
unsigned ext5_tell (int fd);
then you can define and initialize a variable like (the bare name of the function is a pointer to it):
fs_ops ext5_ops = {
.open = ext5_open,
.tell = ext5_tell,
};
Fields that aren't initialized get NULL (i.e., pointer to no function). You can change the value of a field, ask if it is set (if(ext5_ops.seek == NULL) ...), and call the function:
retval = ext5_ops.(*ext5_open)("/tmp/junk");
(the parenteses around (*ext5_open) are because * (pointer indirection) binds less strongly than function call).
A function pointer can be converted into a void *, but it's a little trickier to convert it back to correct function-pointer type in order to call it. It should be possible by using a union. You'll need a separate union-member of the correct type for type of function that you want to store. And, as user4815162342 notes in a comment, you'll need to manage all the various combinations, probably with an enum.
typedef struct
{
union {
void *vp;
void (*v__v)(void);
void (*v__i)(int);
pid_t (*pid__ccp)(const char *);
int (*i__pid)(pid_t);
bool (*b__ccp_u)(const char *, unsigned);
bool (*b__ccp)(const char *);
int (*i__ccp)(const char *);
int (*i__i)(int);
int (*i__i_vp_u)(int, void *, unsigned);
int (*i__i_cvp_u)(int, const void *, unsigned);
void (*v__i_u)(int, unsigned);
unsigned (*u__i)(int);
} fp;
int arg_no;
}td_sys_call_handler;
The idea here is to try to encode the types into the identifiers, as a kind of "apps-Hungarian". This way, the meaning of any of these identifiers is directly visible.
It may be easier to generate these pointers and the associated enum at the same time. I think the easiest way to manage this part is with my favorite trick, X-Macros. Warning: it just gets more and more weird.
#define function_types(_) \
_(v__v, void, void) \
_(v__i, void, int) \
_(pid_ccp, pid_t, const char *) \
_(i__pid, int, pid_t) \
_(b__ccp_u, const char *, unsigned) \
_(b__ccp, const char *) \
_(i__ccp, const char *) \
_(i__i, int) \
_(i__i_vp_u, int, void *, unsigned) \
_(i__i_cvp_u, int, const void *, unsigned) \
_(v__i_u, int, unsigned) \
_(u__i, unsigned, int) \
/* end function_types */
This "master"-macro is a comma separated table of tokens which is passed, row by row, to the _ underscore macro, which is passed-in.
Now the struct type can be constructed by writing additional macros to use the rows, these are passed-in as _ to the table macro to instantiate the template:
#define create_function_pointer(id, ret, ...) \
ret (*id)(__VA_ARGS__);
#define create_function_type_id(id, ret, ...) \
f__ ## id
typedef struct {
union {
void *vp;
function_types(create_function_pointer)
} fp;
int arg_no;
enum {
function_types(create_function_type_id)
} type;
} td_sys_call_handler;
Now an array of these structs can be populated:
td_sys_call_handler ish[SYSCALL_HANDLER_NUM];
int i=0;
ish[i++] = (td_sys_call_handler){ halt, 0, f__v__v };
ish[i++] = (td_sys_call_handler){ exit, 1, f__v__i };
ish[i++] = (td_sys_call_handler){ exec, 1, f__pid__ccp };
ish[i++] = (td_sys_call_handler){ wait, 1, f__i__pid };
ish[i++] = (td_sys_call_handler){ create, 2, f__b__ccp_u };
ish[i++] = (td_sys_call_handler){ remove, 1, f__b__ccp };
ish[i++] = (td_sys_call_handler){ open, 1, f__i__ccp };
ish[i++] = (td_sys_call_handler){ filesize, 1, f__i__i };
ish[i++] = (td_sys_call_handler){ read, 3, f__i__i_vp_u };
ish[i++] = (td_sys_call_handler){ write, 3, f__i__i_cvp_u };
ish[i++] = (td_sys_call_handler){ seek, 2, f__v__i_u };
ish[i++] = (td_sys_call_handler){ tell, 1, f__u__i };
Now, calling a function given one of these structs will require (as you surmised) a switch, with a separate case for each signature. It needs to crack the arguments using stdarg and the call with the appropriate union member function pointer.
void make_sys_call(td_sys_call_handler ish, ...){
va_list ap;
int i;
const char *ccp;
pid_t pid;
bool b;
void *vp;
unsigned u;
const void *cvp;
va_start(ap, ish);
switch(ish.type) {
case f__v__f: ish.fp.v__v();
break;
case f__v__i: i = va_arg(int);
ish.fp.v__i(i);
break;
case f__pid__ccp: ccp = va_arg(const char *);
ish.fp.pid__ccp(ccp);
break;
// etc.
}
va_end(ap);
}
It will not be possible to return different types directly. You will either need to allocate a union type variable to hold the return value and return that, or something even more insane. An external stack data type could hold unions of the various return types. Depending on profiling results, it may be appropriate to consider this instead of returning the unions.
HTH.

error while make runs. Conflicting types and previous declaration

I found an implementation of AES for a project I'm doing.
However when i integrate it I'm getting the following errors during the build.
In file included from ff.h:26:0,
from disp.h:4,
from main.c:14:
aes.h:14:3: error: conflicting types for 'AesCtx'
aes.h:14:3: note: previous declaration of 'AesCtx' was here
aes.h:28:5: error: conflicting types for 'AesCtxIni'
aes.h:28:5: note: previous declaration of 'AesCtxIni' was here
aes.h:29:5: error: conflicting types for 'AesEncrypt'
aes.h:29:5: note: previous declaration of 'AesEncrypt' was here
aes.h:30:5: error: conflicting types for 'AesDecrypt'
aes.h:30:5: note: previous declaration of 'AesDecrypt' was here
The header file itself is:
// AES context structure
typedef struct {
unsigned int Ek[60];
unsigned int Dk[60];
unsigned int Iv[4];
unsigned char Nr;
unsigned char Mode;
} AesCtx;
// key length in bytes
#define KEY128 16
#define KEY192 24
#define KEY256 32
// block size in bytes
#define BLOCKSZ 16
// mode
#define EBC 0
#define CBC 1
// AES API function prototype
int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode);
int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen);
int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen);
and then the respective C file uses.
int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode)
{
// Cut out code for brevity
}
int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen)
{
// Cut out code for brevity
}
int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen)
{
// Cut out code for brevity
}
I know these errors usually occur because either the function hasn't been pre-declared or because it's slightly different to it's declaration, but I can't see a difference.
Any ideas?
What compiler are you using? My best guess that it's trying to say aes.h is being #included twice. Try adding header guards at the beginning and end of the aes.h:
#ifndef AES_H_
#define AES_H_
typedef struct {
...
int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen);
#endif /* !AES_H_ */

Resources