C++ pass reference to function inside same class - c++

I am developing an embedded system with the mbed framework in C++.
To attach an interrupt function to the serial interrupt, I normally do this:
Serial pc(pin_u_tx, pin_u_rx,115200);
void SerialStart(void) {
...
pc.attach(&SerInt);
...
}
void SerInt(){
...
}
But now I need to do the same thing from inside a class, and it doesn't work as I can't refer to an internal function:
CTCOMM::CTCOMM()
{
pc = new Serial(ser_tx, ser_rx, ser_baud);
pc->attach(&serial_interrupt);
}
void CTCOMM::serial_interrupt() {
...
}
I tried a few ways, but none works:
pc->attach(&serial_interrupt);
gives the error
lib\CTcomm\ctcomm.cpp:12:17: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&CTCOMM::serial_interrupt' [-fpermissive]
pc->attach(*serial_interrupt);
gives the error
lib\CTcomm\ctcomm.cpp:12:17: error: invalid use of member function 'void CTCOMM::serial_interrupt()' (did you forget the '
pc->attach(*serial_interrupt());
gives the error
lib\CTcomm\ctcomm.cpp:12:33: error: void value not ignored as it ought to be ()' ?)
pc->attach((*this)->*(serial_interrupt));
gives the error
lib\CTcomm\ctcomm.cpp:12:23: error: invalid use of non-static member function 'void CTCOMM::serial_interrupt()'
and so on (I tried more suggestions found here, but got no succes).
What would be the correct way to point to that function?

Try this.
pc->attach(callback(this, &CTCOMM::serial_interrupt));
pc->attach(this, &CTCOMM::serial_interrupt); should also work. But it is deprecated in the recent versions of mbed OS.
Here is the latest Mbed API:
https://os.mbed.com/docs/v5.10/mbed-os-api-doxy/classmbed_1_1_serial.html

Related

Can unity C unittest framework be used to unittest C++ code?

I'm using the unity framework to unittest my C code on an AtMega32A. This works great. now I wonder if I can somehow trick unity to also test my C++ code.
I've made a small proof of concept program that exposes all the members of the C++ class via a public function. Now I would like to put a number of assert macro's in that public function. The program can be found here:
https://github.com/cdwijs/cpp_unit_test
In my main I have the following:
int main(void)
{
UNITY_BEGIN();
//RUN_TEST(myPrivate.executeTest); //unity_internals.h(707,65): error: invalid use of non-static member function
//RUN_TEST((void*)myPrivate.executeTest); //error: invalid use of member function (did you forget the '()' ?)
//RUN_TEST((func)))myPrivate.executeTest); //error: 'func' was not declared in this scope
//RUN_TEST(&myPrivate.executeTest); //error: cannot convert 'void (Private::*)()' to 'UnityTestFunction {aka void (*)()}' for argument '1' to 'void UnityDefaultTestRun(UnityTestFunction, const char*, int)'
UNITY_END();
myPrivate.more();
myPrivate.more();
myPrivate.less();
/* Replace with your application code */
while (1)
{
}
}
And in Private_test.cpp I have the following:
#include "private.h"
#include "unity.h"
void Private::executeTest (void)
{
myNumber = 3;
TEST_ASSERT_EQUAL_INT(3,myNumber);
more();
TEST_ASSERT_EQUAL_INT(4,myNumber);
}
I can't figure out howto run the test function. Any Idea's? Am I looking in the correct direction, or should I use a test framework that is specifically aimed at C++?

Linux - signal: error: invalid use of non-static member function

I originally wrote some tests to test the functionality of signals for my program. The tests proved promising, however moving the small code changes to my class in my source code has given me a few problems.
I have added two functions: setAlarm(), and a callback alarm_handler. setAlarm() does as it says, which is set the alarm. Once time expires, alarm handler is called which runs an execute function.
a.cpp
int Database::alarm_handler(int signum)
{
dbExecSql();
}
void Database::setAlarm()
{
signal(SIGALRM, alarm_handler);
ualarm(500000,0);
}
b.h
class Database
{
public:
int alarm_handler(int signum);
void setAlarm();
dbExecSql();
};
error
error: invalid use of non-static member function
signal(SIGALRM, alarm_handler);
Any help would be appreciated.
EDIT
I have modified alarm_handler to be removed from my class, however am now am receiving:
error: invalid conversion from ‘int (*)(int)’ to ‘__sighandler_t {aka void (*)(int)}’ [-fpermissive]
signal(SIGALRM, alarm_handler);
^
The signal handler function (alarm_handler) can't be member function and should be a standalone function with C linkage.
Remove it from your class:
void alarm_handler(int signum)
{
dbExecSql();
}
Beware that only async-signal-safe functions can be called from signal handlers safely. So you need to ensure dbExecSql() respects that.

C++ threading - no matching function for call to

This is my first time using threads in c++ and I have some issues with it. I am getting error
error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, __gnu_cxx::__alloc_traits<std::allocator<packetInfo> >::value_type*)’
This is my code excerpt:
std::vector<packetInfo> sentPackets; // global var
void renewIP(struct packetInfo *currentPacket) {
...//code
}
void anotherFuntion() {
...
std::thread renewTimer(renewIP, &(sentPackets[i]));
renewTimer.detach();
...
}
I have absolutely no idea what am I doing wrong or why am I getting the error.
Thanks.
The error tells you directly:
<unresolved overloaded function type>
You must have multiple overloads of renewIP, and the compiler doesn't know which one you want. You can either rename them to make them not ambiguous, or make it explicit via a cast:
std::thread renewTimer((void(*)(struct packetInfo*))renewIP, &(sentPackets[i]));

Unit testing a vector string

I have this really simple line of code in my production-code(A.cpp) as follows:
std::string A::getString(int i) {
return sVect_[i];
}
with the header as follows:
class A{
public:
std::string getString(int i);
...
private:
vector<std::string> sVect_;
...
};
I've been trying to test the getString() function using googletest but an error keeps popping out:
error: invalid conversion from 'char* (*)(const char*, int)throw ()' to 'int'
error: initializing argument 1 of 'std::string A::getString(i)'
This was my test program:
TEST(ATest, getString){
A a;
EXPECT_EQ("c", a.getString(i));
}
I couldn't quite grasp the workaround of the vector string and how to call it in my test program without ever changing the production code. I even use the hack, adding #define statements, to access the private member but still couldn't do it.
How do my test actually looks like to successfully call that function?
Note: I'm on Linux and using gcc. Thank you in advance guys.
Perhaps the error message is misleading. Have you defined i globally somewhere else? To me it looks like in the local scope because it does not know what the value of the variable i is, it is misbehaving in an unexpected way
TEST(ATest, getString){
A a;
EXPECT_EQ("c", a.getString(i)); //here what is the 'i' and where is it defined
}

error: expected primary-expression before ')' token (C)

I am trying to call a function named characterSelection(SDL_Surface *screen, struct SelectionneNonSelectionne sel) which returns a void
This is the .h of the function I try to call:
struct SelectionneNonSelectionne;
void characterSelection(SDL_Surface *screen, struct SelectionneNonSelectionne);
void resetSelection(SDL_Surface *screen, struct SelectionneNonSelectionne);
On my main function, I try to call it like this:
characterSelection(screen, SelectionneNonSelectionne);
When I compile, I have the message:
error: expected primary-expression before ')' token
I made the includes. I suppose I miscall the second argument, my struct. But, I can't find why on the net.
Have you got any idea about what I did wrong?
You should create a variable of the type SelectionneNonSelectionne.
struct SelectionneNonSelectionne var;
After that pass that variable to the function like
characterSelection(screen, var);
The error is caused since you are passing the type name SelectionneNonSelectionne
A function call needs to be performed with objects. You are doing the equivalent of this:
// function declaration/definition
void foo(int) {}
// function call
foo(int); // wat!??
i.e. passing a type where an object is required. This makes no sense in C or C++. You need to be doing
int i = 42;
foo(i);
or
foo(42);
You're passing a type as an argument, not an object. You need to do characterSelection(screen, test); where test is of type SelectionneNonSelectionne.
I seen this problem with the latest nightly build of Code::Blocks. When I switched back to the stable release of Code::Blocks, 20.03 at the time of this writing, the problem went away and my code compiled and ran without problems. I'm not sure what Code::Blocks is doing, but it is very annoying. I got this repeatedly on a C++ project for every NULL in my code, forcing me to use nullptr instead.