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

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.

Related

ESP32: Compile errors when using IRAM_ATTR

I am sure I am doing something really stupid, but here goes..
I get a compile error when I use IRAM_ATTR for my ISR. I am compiling for ESP32.
Here is the definition of the ISR
void
IRAM_ATTR
detectsBlockOccupancy() {
....
ISR code..
...
}
And here is the first usage:
void setup() {
// Set Sensor pin as interrupt, assign interrupt function and set RISING mode
attachInterrupt(digitalPinToInterrupt(BDInterruptPin), detectsBlockOccupancy, RISING);
...
}
The error I get is as follows:
In function 'void setup()': Node0:226:90: error: invalid conversion
from 'int ()()' to 'void ()()' [-fpermissive]
attachInterrupt(digitalPinToInterrupt(BDInterruptPin), detectsBlockOccupancy, RISING);
^ In file included from
C:\Users\vibhas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32/esp32-hal.h:53:0,
from C:\Users\vibhas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32/Arduino.h:35,
from sketch\Node0.ino.cpp:1: C:\Users\vibhas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32/esp32-hal-gpio.h:81:6:
note: initializing argument 2 of 'void attachInterrupt(uint8_t, void
()(), int)' void attachInterrupt(uint8_t pin, void ()(void), int
mode);
^
If I remove the IRAM_ATTR then it compiles fine. It seems to think that I am trying to pass a different type of function pointer.
What could I be doing wrong ?
Thanks
vibhas

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++?

C++ pass reference to function inside same class

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

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
}