'ClassName' and 'ClassInstance' was not declared in this scope - c++

I am attempting to program an Atmel SAM D21 microcontroller using C++ in Atmel Studio. I'm trying to create periodic hardware interrupts using one of the on-chip timers.
I created Timer4 class to set up the timer from main.cpp. I tried to create a Timer4 instance called MyTimer4 in the main function, but it says
'Timer4' was not declared in this scope
'MyTimer4' was not declared in this scope
I've seen many similar discussions pointing to incorrect/circular #includes. But, I don't seem to see the same problem on my own. Any ideas?
Main.cpp
#include "timerSAMD21.h"
#include "sam.h"
void SampleADC(void)
{
}
int main(void)
{
SystemInit();
Timer4 MyTimer4;
MyTimer4.setRate(1000);
MyTimer4.onEvent(SampleADC);
MyTimer4.start;
}
timerSAMD21.h
#ifdef TIMERSAMD21_H
#define TIMERSAMD21_H
#include "tc.h"
#include "tc4.h"
#include "gclk.h"
typedef void (*voidFuncPtr)(void);
class Timer4
{
public:
Timer4() {};
void setRate(int frequency);
void start(void);
void end(void);
void onEvent(voidFuncPtr funcOnEvent);
private:
void configure(int frequency);
void enable(void);
void disable(void);
void reset(void);
};
#endif
timerSAMD21.cpp
#include "timerSAMD21.h"
voidFuncPtr callback = NULL;
void Timer4::setRate(int frequency) {
configure(frequency);
}
void Timer4::start(void) {
enable();
}
void Timer4::end(void) {
disable();
reset();
}
void Timer4::configure(int frequency) {
//Configuration code here. Removed for Stack Overflow.
}
void Timer4::enable(void){
REG_TC4_CTRLA |= TC_CTRLA_ENABLE; //Enable timer
while (TC4->COUNT8.STATUS.bit.SYNCBUSY);
}
void Timer4::disable(void) {
REG_TC4_CTRLA &= ~TC_CTRLA_ENABLE;
while (TC4->COUNT8.STATUS.bit.SYNCBUSY);
}
void Timer4::reset(void) {
REG_TC4_CTRLA = TC_CTRLA_SWRST;
while (TC4->COUNT8.STATUS.bit.SYNCBUSY);
while (TC4->COUNT8.CTRLA.bit.SWRST);
}
void Timer4::onEvent(voidFuncPtr funcOnEvent){
callback = funcOnEvent;
}
#ifdef __cplusplus
extern "C" {
#endif
void IRQHandlerTimer4(void) {
if (callback != NULL)
{
callback();
}
REG_TC4_INTFLAG = TC_INTFLAG_MC0;
}
#ifdef __cplusplus
}
#endif

(Note: Making an answer in order to get this out of the list of unanswered questions. Miles seems to have decided not to answer and I do not consider the problem a typo.)
The way you attempt to prevent the reinclusion of your header is causing it to only make the content of the header visible if the guard-macro happens to be defined already, which it of course never is.
In order to fix this, change the
#ifdef TIMERSAMD21_H
#define TIMERSAMD21_H
into
#ifndef TIMERSAMD21_H
#define TIMERSAMD21_H
This will first keep the header content visible the first time it is included.
It will then define the guard macro, which will prevent the header content from being compiled a second time in the same translation unit, i.e. code file.

Related

Call a function in the main program from an imported DLL

I am trying to create a program that uses plugins in C++ to get some experience with importing and exporting functions from .dll and .so libraries. For simplicity's sake let's only use .dll libraries here.
What I'm trying to do is to make the communication between the plugin and the main program that loaded it "two-way", meaning the main program can call functions from the plugin (this is solved) and the plugin should be able to call functions from the main program (this I'm having trouble with).
I currently am able to create a .dll where I exported the functions with extern "C" {} and __declspec(export).
TestPlugin.h
#pragma once
extern "C" {
__declspec(dllexport) const char* pluginName();
__declspec(dllexport) void onLoad();
__declspec(dllexport) void onShutdown();
}
TestPlugin.cpp
#include "TestPlugin.h"
#include <iostream>
const char * pluginName()
{
return "Test Plugin";
}
void onLoad()
{
std::cout << "onLoad() called!" << std::endl;
}
void onShutdown()
{
std::cout << "onShutdown() called!" << std::endl;
}
I am then loading this test plugin with the following (shortened) code. I removed the error checking and console output.
Plugin.h
#pragma once
#include <filesystem>
#include <iostream>
#include <windows.h>
class Plugin
{
private:
typedef const char*(*pluginNameType)();
typedef void(*onLoadType)();
typedef void(*onShutdownType)();
HINSTANCE m_lib;
public:
Plugin(std::filesystem::path filename);
~Plugin();
pluginNameType pluginName;
onLoadType onLoad;
onShutdownType onShutdown;
};
Plugin.cpp
#include "Plugin.h"
Plugin::Plugin(std::filesystem::path filename)
{
m_lib = LoadLibrary(filename.wstring().c_str());
pluginName = (pluginNameType)GetProcAddress(m_lib, "pluginName");
onLoad = (onLoadType)GetProcAddress(m_lib, "onLoad");
onShutdown = (onShutdownType)GetProcAddress(m_lib, "onShutdown");
}
Plugin::~Plugin()
{
FreeLibrary(m_lib);
}
What I can do now is to call the functions in the plugin (TestPlugin.cpp) from my main program.
main.cpp
Plugin *plugin = new Plugin("pathToDLLGoesHere");
plugin->onLoad();
plugin->onShutdown();
What I would like to do now is to also enable the test plugin I just loaded to have access to functions that are defined in the main program. So let's say in my main.cpp I have something like this ...
main.cpp
int testCall(int val) {
return val + 1;
}
int main()
{
...
return 0;
}
... how would I be able to call the testCall() from the test plugin?
Would it be as simple as to send the function pointer to the plugin and use it? Or do I need to take a different approach here? Thank you for your help!
I have figured out how this works. You can also use extern "C" {} and __declspec(dllexport) to export functions from your main program so the DLLs can see them and when you get the handle of your main program in the DLL, the functions can be called.
In one of your headers in your main program you export the function.
main.h
extern "C" {
__declspec(dllexport) int testCall(int val);
}
main.cpp
int testCall(int val) {
return val + 1;
}
In my test plugin header I created a handle for the main program and a definition for the function I am trying to call from main.
TestPlugin.h
#pragma once
#include <windows.h>
HINSTANCE app;
int(*testCall)(int val);
...
In the body I then assign the handle (calling GetModuleHandle with a nullptr will give you the handle of your program) and then get the exported function from my main program.
TestPlugin.cpp
app = GetModuleHandle(nullptr);
testCall = (int(*)(int val))GetProcAddress(app, "testCall");
After that, I can just call the function.
std::cout << testCall(5) << std::endl;

Include .c files in Unit test project and get access to it from multiple cpp files without linking problems

I'm doing functional testing on c code. Have include .c file in test .cpp file so far, everything works well. But I need to include the same .c file in another .cpp file where I do other unit tests. Then I get problems that is already defined. Because I already include it in the first file cpp.
If merge all the test methods into one cpp file then it works well. If keep all unit test in one file get to big handle so I need to split up diffrent files in same project it also create help functions for secure that functions get in capsules.
This not a normal LNK2005 because I can not declare the variable and functions in .h: as extern BOOL MyBool; and then assign to it in a .c or .cpp file. Because need include c file as I do unit test this function. Also I can't or should avoid do any changes .c.
I looking way to keep include of .c local not effect other files in same project.
source.h
#ifndef SOURCE_H_
#define SOURCE_H_
#include "../car.h"
enum INITIALMODE {
INITIALMODE_NOT_POSITIONING, // 0
INITIALMODE_NO_DRIVER_INPUT, // 1
INITIALMODE_POSITION_LOW_POSITION, // 2
INITIALMODE_POSITION_STANDARD_POSITION, // 3
INITIALMODE_POSITION_HIGH_POSITION // 4
};
void initMotor(void);
#endif
source.c
/* Compiler include files */
#pragma once
#include "positioning.h"
#include "api.h"
#include "drive.h"
#include "types.h"
static void updateTarget(void);
static SWord getMax(UWord Limit, UWord Aux);
static DWord getHeight(void);
static Bool isMode(void);
static Bool isExiting(void);
#define cMaxHeight 100 * Profile.s.Max /* m -> mm */
void initMotor(void)
{
// do something
}
static void updatePositioning(void)
{
// do something
}
Test files look like this, however, this is very scaled for making exemple small.
UnitTest.cpp and UnitTest2.cpp
#include "CppUnitTest.h"
#ifndef UNIT_TEST
#define UNIT_TEST
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace Test
{
extern "C" {
#include "../../Test/source.h"
#include "../../Test/source.c"
}
TEST_CLASS(UnitTest_1)
{
public:
TEST_METHOD(Test_1)
{
// Verify that the initial state is as expected.
initTest();
//Expected value
UWord Expected = 500
//Trigger to execute.
UWord Test = updatePositioning();
// Verify that the results are as expected.
Assert::AreEqual(Expected, Test);
}
};
}
#endif
You should never include a .C or .CPP file.
However, you can compile C code in C++. Here's an example based on the information you gave in your initial post.
YourCCode.h
#ifndef YourCCode_H
#define YourCCode_H
int FunctionToTest(int SomeParams);
int TestStaticFunctions(int SomeParam1, int SomeParam2);
#endif // YourCCode_H
YourCCode.c
#include "YourCCode.h"
static int SomeStaticFunction(int Param1, int Param2)
{
return Param1 + Param2; // that needs extensive testing, obviously.
}
int FunctionToTest(int SomeParams)
{
return SomeStaticFunction(SomeParams, 1);
}
int TestStaticFunctions(int SomeParam1, int SomeParam2)
{
return SomeStaticFunction(SomeParam1, SomeParam2);
}
UnitTest1.cpp
extern "C" {
#include "YourCCode.h"
}
bool TestFunction(int Value)
{
return (FunctionToTest(Value) == Value+1);
}
UnitTest2.cpp
extern "C" {
#include "YourCCode.h"
}
void AnotherTestFunction(int Val, int Val2)
{
int newValue = TestStaticFunctions(Val, Val2);
ASSERT(newValue == Val+Val2);
}
Then compile your CPP and C file.
After you clarified your intent, I realized you're trying to test static functions from another unit. Static function, by definition, are only available to other functions in the same translation unit. This is mostly use as a protection to prevent programmers to call some functions without knowing how to validate their inputs, know the call order, etc...
My best bet here is either you choose that your functions are not static and you can test them from outside your translation unit, or you implement the test functions inside the translation unit containing those static functions. I would recommend the latter as a translation unit should know (architecturally speaking) how to test their own features.
As a third solution, if you don't have any control over the content of the C file (but since you have that C file, I doubt it), you could have a proxy CPP file that includes the C file, and create a proxy call for each static call.
That is a ugly hack, though, and could break very easily if the C file ever gets updated, so I'm advising against it.
Here's a quick example :
YourCCode.h
#ifndef YourCCode_H
#define YourCCode_H
void SomeFunction(void);
#endif // YourCCode_H
YourCCode.c
#include "YourCCode.h"
static int AddSomething(int Param1, int Param2)
{
return Param1 + Param2;
}
static int SubtractSomething(int Param1, int Param2)
{
return Param1 - Param2;
}
void SomeFunction(void)
{
// code meant to be called externally.
}
ProxyTestCode.hpp
bool TestAddSomething(void);
bool TestSubtractSomething(void);
ProxyTestCode.cpp
extern "C" {
#include "YourCCode.h"
#include "YourCCode.c"
}
bool TestAddSomething(void)
{
return (AddSomething(2,2) == 4);
}
bool TestSubtractSomething(void)
{
return (AddSomething(2,2) == 0);
}
UnitTest1.cpp
#include "ProxyTestCode.hpp"
void TestAdd(void)
{
ASSERT(TestAddSomething());
}
UnitTest2.cpp
#include "ProxyTestCode.hpp"
void TestSubtract(void)
{
ASSERT(TestSubtractSomething());
}
If you do that, don't compile your C file in your project.

Arduino: pass function to class, returning String

I'm trying to get my Arduino class to return String messages with all kind of information for logging. With lots of trial and error I manage to pass a reference to the logging function to the class, but can only get a char* but not a String, and I want to be able to send Strings making it so much easier to send back all kinds of data.
I have the first part working already.
The sketch:
#include <Test.h>
#include <string.h>
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.\n");
t.doSomething("This is even more useful.\n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}
The header file:
#ifndef TEST_h
#define TEST_h
class Test
{
public:
Test(); // The constructor.
void setLogging(void (*)(char*)); // Takes function setting where to log.
void doSomething(char*);
};
#endif
The class:
#include <Test.h>
typedef void (*LogFunction)(char*);
LogFunction writeLog;
Test::Test () {
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
void Test::setLogging (void (*f)(char*) ) {
writeLog = f;
return;
}
Now what I want my class to be able to do is send information like this, as String, rather than char* (I also haven't found an easy way of converting "anything" to char* and then concatenating the two or more strings):
writeLog ("HydroMonitorECSensor::setCalibration Receiving calibration - haveCalibration = " + String(haveCalibration));
writeLog ("HydroMonitorECSensor::setCalibration calibratedSlope = " + String(calibratedSlope));
writeLog ("HydroMonitorECSensor::setPins capPos set to " + String(capPos));
Where haveCalibration is a bool (which as String becomes either "true" or "false"), calibratedSlope is a double and capPos is an int. This way I can easily and cleanly send complete lines to the logger. Works great within the main script - not from the class.
I tried simply changing the char* to String and adding #include <string.h> to the library files but it doesn't work.
In Test.cpp I then get void Test::setLogging (void (*f)(String) ) { and in Test.h void setLogging(void (*)(String)); and now I get error messages:
In file included from /home/wouter/Arduino/libraries/Test/Test.cpp:1:0:
/home/wouter/Arduino/libraries/Test/Test.h:10:29: error: expected ',' or '...' before '(' token
void setLogging(void (*)(String)); // Takes function setting where to log.
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:40: error: variable or field 'setLogging' declared void
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:31: error: 'f' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:34: error: 'String' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
Suggestions?
Additional info, maybe important: I'm using the Arduino IDE and compile for ESP8266.
You are using the Arduino-provided String class, but didn't include the Arduino.h header in your test.h header file. That causes it to not find the String class and compilation fails.
The following works:
main.cpp:
#include <Arduino.h>
#include <test.hpp>
void writeLog (char* message);
void writeLog (String message);
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.\n");
t.doSomething("This is even more useful.\n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}
test.hpp:
#ifndef TEST_h
#define TEST_h
#include <Arduino.h> //for "String" class
//Typdef for the log function. Takes a String, returns nothing
typedef void (*LogFunction)(String);
class Test
{
public:
Test(); // The constructor.
// void setLogging(void (*)(char*)); // Takes function setting where to log.
void setLogging(LogFunction); //use the typedef here
void doSomething(char*);
};
#endif
test.cpp:
#include <test.hpp>
LogFunction writeLog;
Test::Test () {
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
//void Test::setLogging (void (*f)(char*) ) {
void Test::setLogging (LogFunction f) { //also use typedef here
writeLog = f;
return;
}
Among other things that may arise, the compiler tells you that it cannot resolve identifier String.
This can have several reasons: First, you write String, and not string (note the capital letter in your writing). Second, if you write string and not std::string, it cannot be resolved unless you have either declared using namespace std (which is not the preferred variant for several reasons) or using std::string. Third, class std::string is declared in header <string>, which is something different than <string.h>.
So I'd write #include <string> and use then std::string.

How to define a "global" struct?

Let say I've decleared this within MyTools.h
#ifndef _MYTOOLS_
#define _MYTOOLS_
typedef struct {
// const
double LN20;
double LN40;
// methods
double NoteToFrequency(int noteNumber);
} Tool;
extern const Tool tool;
#endif // !_MYTOOLS_
For every compilation unit, there is only a global/const/unique instance of Tool. Exactly what I want.
But now: how can I define it? In the .h i've only declared it. How can I define it in .cpp? Tried somethings like:
tool.LN20 = 1.34;
But of course it doesn't works. And the method's definition?
extern doesn't define any variable it just declares it. What you wan't to achieve can be done as below:
The link Global const object shared between compilation units explains how to do it with extern const
t.h file
#ifndef _MYTOOLS_
#define _MYTOOLS_
struct Tool {
// const
double LN20;
double LN40;
double NoteToFrequency(int noteNumber);
} ;
extern const Tool tool ;
#endif // !_MYTOOLS_
t1.cpp
#include "t.h"
#include <stdio.h>
void use_tool()
{
printf("%f\n",tool.LN20);
printf("%f\n",tool.LN40);
return;
}
t2.cpp
#include "t.h"
#include <stdio.h>
const Tool tool = {.LN20 = 20.0, .LN40 = 30.2};
double Tool::NoteToFrequency(int noteNumber)
{
return 12.0;
}
void use1_tool()
{
printf("%f\n",tool.LN20);
printf("%f\n",tool.LN40);
return;
}
int main()
{
void use_tool();
use_tool();
use1_tool();
return 0;
}
Hope this helps.

Accessing Methods in Declaration vs Implementation

I'm having difficulty interpreting some of my results, which I would expect to behave the same but are not.
I am trying to write a method that returns a function pointer getPtrFn
I have a main.c file reading
#include <iostream>
#include "test.hpp"
int main(int argc, char* argv[]){
Test test;
void (*fPtr)(void) = test.getPtrFn();
return 0;
}
A test.hpp file that reads
#ifndef _test_h
#define _test_h
class Test {
private:
void (*ptrFn)(void);
public:
Test(){};
void (*getPtrFn(void))(void){
return ptrFn;
};
~Test();
};
#endif
And a test.cpp file that reads
#include "test.hpp"
Test::~Test(){}
This runs fine. However, when I move the implementation for *getPtrFn(void) to the implementation file (revised files shown below),
test.hpp:
#ifndef _test_h
#define _test_h
class Test {
private:
void (*ptrFn)(void);
public:
Test(){};
void (*getPtrFn(void))(void);
~Test();
};
#endif
test.cpp:
#include "test.hpp"
void (Test::*getPtrFn)(void){
return ptrFn;
};
Test::~Test(){}
I get the compile error
test.cpp:16:9: error: use of undeclared identifier 'ptrFn'
My understanding of the language syntax is that they would be treated the same. So what gives?
-Jeff
You need
void(*Test::getPtrFn(void))(void)
{
return ptrFn;
}
instead of void (Test::*getPtrFn)(void){...}. void (Test::*getPtrFn)(void) is the declaration of getPtrFn as a pointer-to-Test-member-function taking no parameters (void) and returning void, so after you put the braces { ... } you get a compile-time error (its like trying to declare int i{/*some statemets*/}).
Also, and don't forget to keep the declaration
void(*getPtrFn(void))(void);
in your header (right now it seems you don't have it, did you cut/pasted it?).
Quite a horrible thing to look at... So really, use a type alias, it makes your code much cleaner.
using PTRFN = void(*)(void); // or typedef void(*PTRFN)(void);
class Test {
private:
PTRFN ptrFn;
public:
PTRFN getPtrFn(void);
Test(){};
~Test(){};
};
PTRFN Test::getPtrFn(void) // clear an concise
{
return ptrFn;
}
In case you really really want to be able do decipher every kind of pointer declaration you can think of, try looking at the clockwise/spiral rule, I found it extremely useful, clear and easy to understand. Then test your knowledge at cdecl.org.