C++ wrappers for C struct api
-
Hi all, I am new to this forum and generally any programming help forum for that matter. I have a case where i want to maintain both C and C++ api library. So therefore i choose to make my C++ support a thin wrapper around the C code. However, i do not know what is the most effective way to achieve this without unnecessary memory and performance overhead. Below is an example case. /*Begin Code Sample*/ /*Start time.h*/ struct Time { int seconds, int nanoseconds }; void timeAdd(struct Time* time, struct Time* delta); void timeSub(struct Time* time, struct Time* delta); /*End time.h*/ /*Start timer.h*/ struct Timer { struct Time time; void (*callback)(struct Timer *timer); }; void timerSetCallback(struct Timer *timer, void (*callback)(struct Timer *timer)); void timerStart(struct Timer *timer); void timerStop(struct Timer *timer); /*End timer.h*/ /*Start time.hxx*/ namespace C { #include "time.h" } class Time { public: Time() { m_time.seconds = 0; m_time.nanoseconds = 0; }; ~Time(){}; int seconds(){return m_time.seconds;} int nanoseconds(){return m_time.nanoseconds;} void setSeconds(int seconds){m_time.seconds = seconds}; void setNanoseconds(int nanoseconds){m_time.nanoseconds = nanoseconds}; void add(Time &time){C::timeAdd(&m_time, &time.m_time);}; void sub(Time &time){C::timeSub(&m_time, &time.m_time);}; protected: C::Time m_time; }; /*End time.hxx*/ /*Start timer.hxx*/ #include "timer.h" class Timer : public Time { public: Timer():Time(){m_timer.callback = &Timer::callback;}; ~Timer(){C::timerStop(&m_timer);}; start(){m_timer.time = m_time; C::timerStart(&m_timer);}; stop(){C::timerStop(&m_timer);}; protected: static void callback(struct Timer *timer); C::Timer m_timer; }; /*End Code Sample*/ Now while this works for this simple case, it has a few drawbacks like the additional memory used to allocate m_time in class Time when all of struct Time api's would have even worked for struct Timer and hence struct Time m_time could have been "replaced" by struct Timer m_time but instead both exist in class Timer. It also is the simpler of the cases where the struct sizes are relatively small and the call to Timer::start() was easily managed by a copy of the struct. So now, my question is how can c++ wrappers be written for such cases without the additional memory overhead? Given their similarity, I definitely want class Timer to be a subclass of class Time! However, i do have the flexi
-
Hi all, I am new to this forum and generally any programming help forum for that matter. I have a case where i want to maintain both C and C++ api library. So therefore i choose to make my C++ support a thin wrapper around the C code. However, i do not know what is the most effective way to achieve this without unnecessary memory and performance overhead. Below is an example case. /*Begin Code Sample*/ /*Start time.h*/ struct Time { int seconds, int nanoseconds }; void timeAdd(struct Time* time, struct Time* delta); void timeSub(struct Time* time, struct Time* delta); /*End time.h*/ /*Start timer.h*/ struct Timer { struct Time time; void (*callback)(struct Timer *timer); }; void timerSetCallback(struct Timer *timer, void (*callback)(struct Timer *timer)); void timerStart(struct Timer *timer); void timerStop(struct Timer *timer); /*End timer.h*/ /*Start time.hxx*/ namespace C { #include "time.h" } class Time { public: Time() { m_time.seconds = 0; m_time.nanoseconds = 0; }; ~Time(){}; int seconds(){return m_time.seconds;} int nanoseconds(){return m_time.nanoseconds;} void setSeconds(int seconds){m_time.seconds = seconds}; void setNanoseconds(int nanoseconds){m_time.nanoseconds = nanoseconds}; void add(Time &time){C::timeAdd(&m_time, &time.m_time);}; void sub(Time &time){C::timeSub(&m_time, &time.m_time);}; protected: C::Time m_time; }; /*End time.hxx*/ /*Start timer.hxx*/ #include "timer.h" class Timer : public Time { public: Timer():Time(){m_timer.callback = &Timer::callback;}; ~Timer(){C::timerStop(&m_timer);}; start(){m_timer.time = m_time; C::timerStart(&m_timer);}; stop(){C::timerStop(&m_timer);}; protected: static void callback(struct Timer *timer); C::Timer m_timer; }; /*End Code Sample*/ Now while this works for this simple case, it has a few drawbacks like the additional memory used to allocate m_time in class Time when all of struct Time api's would have even worked for struct Timer and hence struct Time m_time could have been "replaced" by struct Timer m_time but instead both exist in class Timer. It also is the simpler of the cases where the struct sizes are relatively small and the call to Timer::start() was easily managed by a copy of the struct. So now, my question is how can c++ wrappers be written for such cases without the additional memory overhead? Given their similarity, I definitely want class Timer to be a subclass of class Time! However, i do have the flexi
In case you don't know in C++ struct and class is basically the same thing. There is only one difference - in struct the default access is public while in class default access in private. So you can write code like this.
struct Time
{
int seconds,
int nanoseconds
};void timeAdd(struct Time* time, struct Time* delta);
void timeSub(struct Time* time, struct Time* delta);class CTime : protected Time
{
CTime()
{
seconds = 0;
nanoseconds = 0;
}// Add other functions here and just call c functions.
};
Hope this helps. -Saurabh
-
In case you don't know in C++ struct and class is basically the same thing. There is only one difference - in struct the default access is public while in class default access in private. So you can write code like this.
struct Time
{
int seconds,
int nanoseconds
};void timeAdd(struct Time* time, struct Time* delta);
void timeSub(struct Time* time, struct Time* delta);class CTime : protected Time
{
CTime()
{
seconds = 0;
nanoseconds = 0;
}// Add other functions here and just call c functions.
};
Hope this helps. -Saurabh
Yes. I am aware of that. So that is easy when i have to create class Time but then what do i do with class Timer?
Cheers! Kishore
-
Hi all, I am new to this forum and generally any programming help forum for that matter. I have a case where i want to maintain both C and C++ api library. So therefore i choose to make my C++ support a thin wrapper around the C code. However, i do not know what is the most effective way to achieve this without unnecessary memory and performance overhead. Below is an example case. /*Begin Code Sample*/ /*Start time.h*/ struct Time { int seconds, int nanoseconds }; void timeAdd(struct Time* time, struct Time* delta); void timeSub(struct Time* time, struct Time* delta); /*End time.h*/ /*Start timer.h*/ struct Timer { struct Time time; void (*callback)(struct Timer *timer); }; void timerSetCallback(struct Timer *timer, void (*callback)(struct Timer *timer)); void timerStart(struct Timer *timer); void timerStop(struct Timer *timer); /*End timer.h*/ /*Start time.hxx*/ namespace C { #include "time.h" } class Time { public: Time() { m_time.seconds = 0; m_time.nanoseconds = 0; }; ~Time(){}; int seconds(){return m_time.seconds;} int nanoseconds(){return m_time.nanoseconds;} void setSeconds(int seconds){m_time.seconds = seconds}; void setNanoseconds(int nanoseconds){m_time.nanoseconds = nanoseconds}; void add(Time &time){C::timeAdd(&m_time, &time.m_time);}; void sub(Time &time){C::timeSub(&m_time, &time.m_time);}; protected: C::Time m_time; }; /*End time.hxx*/ /*Start timer.hxx*/ #include "timer.h" class Timer : public Time { public: Timer():Time(){m_timer.callback = &Timer::callback;}; ~Timer(){C::timerStop(&m_timer);}; start(){m_timer.time = m_time; C::timerStart(&m_timer);}; stop(){C::timerStop(&m_timer);}; protected: static void callback(struct Timer *timer); C::Timer m_timer; }; /*End Code Sample*/ Now while this works for this simple case, it has a few drawbacks like the additional memory used to allocate m_time in class Time when all of struct Time api's would have even worked for struct Timer and hence struct Time m_time could have been "replaced" by struct Timer m_time but instead both exist in class Timer. It also is the simpler of the cases where the struct sizes are relatively small and the call to Timer::start() was easily managed by a copy of the struct. So now, my question is how can c++ wrappers be written for such cases without the additional memory overhead? Given their similarity, I definitely want class Timer to be a subclass of class Time! However, i do have the flexi
Hi, you're doing something i don't get. on the C Side you got
struct Time { int seconds, int nanoseconds };
and
struct Timer { struct Time time; void (*callback)(struct Timer *timer); };
The Timer struct encapsulates the Time struct, because in C you don't have inheritance. This is correct. But on the C++ side you got
class Time { public: // constructor & destructor ... // functions ... protected: C::Time m_time; };
and
class Timer : public Time { public: // constructor & destructor ... // functions ... protected: static void callback(struct Timer *timer); C::Timer m_timer; };
Here you make some design error. The class time encapsulates the 'c' Time struct and giving it some extra functionality. No problem so far. But you're class Timer inherits from the Time class and encapsulates the 'c' timer struct. Giving you indeed twice the 'c' time struct. According to me this is a fault in the design. The 'C' and 'C++' counterparts are NOT equivalent. To make the equivalent you should encapsulate either the 'C' Timer struct, or, inherit from the Time class and adding the needed Callback function. But you can't do both. Why do you inherit from the time class?
Learn from the mistakes of others, you may not live long enough to make them all yourself.
-
Yes. I am aware of that. So that is easy when i have to create class Time but then what do i do with class Timer?
Cheers! Kishore
With the code you provided I don't think you cannot wrap Timer in C++. Can you share how about about how timer callback is used? -Saurabh
-
Hi, you're doing something i don't get. on the C Side you got
struct Time { int seconds, int nanoseconds };
and
struct Timer { struct Time time; void (*callback)(struct Timer *timer); };
The Timer struct encapsulates the Time struct, because in C you don't have inheritance. This is correct. But on the C++ side you got
class Time { public: // constructor & destructor ... // functions ... protected: C::Time m_time; };
and
class Timer : public Time { public: // constructor & destructor ... // functions ... protected: static void callback(struct Timer *timer); C::Timer m_timer; };
Here you make some design error. The class time encapsulates the 'c' Time struct and giving it some extra functionality. No problem so far. But you're class Timer inherits from the Time class and encapsulates the 'c' timer struct. Giving you indeed twice the 'c' time struct. According to me this is a fault in the design. The 'C' and 'C++' counterparts are NOT equivalent. To make the equivalent you should encapsulate either the 'C' Timer struct, or, inherit from the Time class and adding the needed Callback function. But you can't do both. Why do you inherit from the time class?
Learn from the mistakes of others, you may not live long enough to make them all yourself.
Here you make some design error. The class time encapsulates the 'c' Time struct and giving it some extra functionality. No problem so far. But you're class Timer inherits from the Time class and encapsulates the 'c' timer struct. Giving you indeed twice the 'c' time struct. According to me this is a fault in the design. The 'C' and 'C++' counterparts are NOT equivalent. To make the equivalent you should encapsulate either the 'C' Timer struct, or, inherit from the Time class and adding the needed Callback function. But you can't You are absolutely right. This is the exact problem that i want to solve when writing C++ wrappers. Why do you inherit from the time class? Because the many API's associated with class Time are are also applicable for class Timer. Also, the code presented here is one of the simpler case. The other code that i use also have similar use cases but are somewhat more complex.
Cheers! Kishore
-
With the code you provided I don't think you cannot wrap Timer in C++. Can you share how about about how timer callback is used? -Saurabh
Saurabh.Garg wrote:
With the code you provided I don't think you cannot wrap Timer in C++. Can you share how about about how timer callback is used?
The code that i present here is not the actual code i use but is similar. With regard to the callback, i am currently exploring the use of the code i found from an article here on FastDelegate.
Cheers! Kishore
-
Saurabh.Garg wrote:
With the code you provided I don't think you cannot wrap Timer in C++. Can you share how about about how timer callback is used?
The code that i present here is not the actual code i use but is similar. With regard to the callback, i am currently exploring the use of the code i found from an article here on FastDelegate.
Cheers! Kishore
Yes for member function callbacks you need delegates. I didn't suggest that earlier because I was not able to think how you would write a wrapper in C++ using delegates over C structures. I think you can port the code to C++, meaning the C and C++ code bases will be different. I myself use delegates from Fast C++ Delegate[^]. There are lots of delegates article on code project but I find this one to be easiest to use. -Saurabh