this is probably a beginners question (I did not go to school for this), but it is stalling me for two days now.
I am writing a sketch in Arduino to move a robot. I store my positions in an array like
int joint1[180];
I got it perfectly working and running if everything is in the robot.ino, but now I want to put this array in a home-made library stringer.h and stringer.cpp but acces it from the .ino to make it a little easier to understand for someone else.
the question redefined i readout a home made jcode from sd in the form of a string i put the values to a int whit the toint comand then i store this value in 7 arrays joint1[180] joint2[180] etc now i want to use the array in my main script robot.ino how do i acces the array whitin stringer.ccp or do i put the arrays in my .ino file and make stringer send a string to robot.ino and devide it there ..... this makes it realy hard for the other functions in stringer ????
test situation
globals.h
//#include "Arduino.h"
//#include "StandardCplusplus.h"
//#include <vector>
#include "globals.h"
extern int Joint1[180];
extern int Joint2[180];
extern int Joint3[180];
extern int Joint4[180];
extern int Joint5[180];
extern int Joint6[180];
extern int Slomo[180];
globals.cpp
//#include "Arduino.h"
//#include "StandardCplusplus.h"
//#include <vector>
#include "globals.h"
int Joint1[180];
int Joint2[180];
int Joint3[180];
int Joint4[180];
int Joint5[180];
int Joint6[180];
int Slomo[180];
tester.ino
//#include "StandardCplusplus.h"
#include <globals.h>
int check = 100;
int temp = 0;
void setup() {
for (int p = 0;p < check; p++){
Joint1[p] = p + 33;}
}
void loop() {
if (temp < check){Serial.println(Joint1[temp]);temp = temp + 1;}
}
the other way
globals.h
#include "Arduino.h"
#include "StandardCplusplus.h"
#include <vector>
#include "globals.h"
extern std::vector<int> Joint1;
extern std::vector<int> Joint2;
extern std::vector<int> Joint3;
extern std::vector<int> Joint4;
extern std::vector<int> Joint5;
extern std::vector<int> Joint6;
extern std::vector<int> Slomo;
globals.cpp
#include "Arduino.h"
#include "StandardCplusplus.h"
#include <vector>
#include "globals.h"
std::vector<int> Joint1(180);
std::vector<int> Joint2(180);
std::vector<int> Joint3(180);
std::vector<int> Joint4(180);
std::vector<int> Joint5(180);
std::vector<int> Joint6(180);
std::vector<int> Slomo(180);
i wil get a error: #include nested too deeply
Don't use arrays. They're bad, especially since you're new to programming. Use an std::vector instead. Declare the vector in a header file, like globals.h:
#ifndef GLOBALS_H
#define GLOBALS_H
#include <vector>
extern std::vector<int> joint1;
#endif
Note the extern keyword. This means that this is only a declaration for joint1. Define the vector in a source file, like globals.cpp:
#include "globals.h"
std::vector<int> joint1(180);
When you compile, make sure to also compile globals.cpp with the rest of your sources.
In source files where you need access to joint1, make sure to:
#include "globals.h"
You can access elements in the vector the same way as you do with arrays:
joint1[index]
Although since you said you're new to programming, I'd recommend you use the at() function of vector instead:
something = joint1.at(index);
joint1.at(index) = something;
// etc.
I recommend it because it checks whether you're trying to access an element outside the vector. If for example you try:
joint.at(200)
the program with abort with an exception.
Now, with that being said, having global variables like this gets tedious and difficult to work with. It's better to not use global variables and instead define your functions to take the data you need in function arguments.
If you don't have access to the C++ standard library, and thus std::vector isn't available, then you can keep using arrays instead. extern declaration in globals.h:
extern int joint1[180];
and definition in the .cpp:
int joint1[180];
No more .at() or anything else though. Just plain old [index].
Related
I have a header file in which there is a 2d array extern declaration, and a cpp file in which there is the actual definition for the array for it to link to. I would like to replace this array with a 2d vector, but my compiler keeps telling me:
'A': redefinition; multiple initialization
Here is my code
header.h
#ifndef HEADERS_H_DECLARED
#define HEADERS_H_DECLARED
#include <vector>
...
extern std::vector<std::vector<int>> A(10, std::vector<int>(10));
...
#endif
A.cpp
#include "headers.h"
...
std::vector<std::vector<int>> A(10, std::vector<int>(10));
...
Then in all my other .cpp files I use this vector. When It was an array it all worked fine, I assume it has something to do with my syntax for declaring a 2 dimensional vector across multiple files but I have no idea!
Like this:
header.h:
#ifndef HEADERS_H_DECLARED
#define HEADERS_H_DECLARED
#include <vector>
extern std::vector<std::vector<int>> A;
#endif
A.cpp:
#include "header.h"
std::vector<std::vector<int>> A(10, std::vector<int>(10));
Make sure to spell the names of your files correctly.
I have an array called vel declared inside global.h and defined inside global.cpp. When I try to use it inside a function, get_velocities(), of another class called Robot (inside Robot.cpp), it says:
undefined reference to `vel'
Here are the three files:
1) global.h
#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED
#include <array>
using std::cout;
using std::cin;
using std::endl;
using std::array;
static constexpr const int marker_num = 10;
static constexpr const int dim = (2 * marker_num) + 3;
extern array <float, 3> vel;
#endif // GLOBAL_H_INCLUDED
2) global.cpp
#include <iostream>
#include <cstdio>
#include <cmath>
#include "global.h"
#include "WorldState.h"
#include "Robot.h"
#include "Sensor.h"
#include "Marker.h"
array <float, 3> vel = {0.0, 0.0, 0.0};
3) Robot.cpp
#include <iostream>
#include <cstdio>
#include <cmath>
#include "global.h"
#include "WorldState.h"
#include "Robot.h"
#include "Sensor.h"
#include "Marker.h"
Robot::Robot(float a, float b, float c){
//ctor
x = a;
y = b;
theta = c;
}
void Robot::get_velocities(){
v_tx = 1.0;
v_ty = 0.0;
omega_t = 0.0;
vel = {v_tx, v_ty, omega_t};
}
Edit:
I did read this question . What I realized was that the global variable requires not just a declaration but also a definition. I have provided this definition inside global.cpp. Also when I include #include "global.cpp" in Robot.cpp, it works (But this is not an acceptable practice). So, I believe this error is due to global.cpp not linking properly.
1) Isn't it a common practice to declare global variables in global.h and keep the definitions in global.cpp? How do I link them properly? I believe that one way is to create a proper make file. However, I am using codeblocks IDE. How do I do it in this IDE?
2) Is it better to eliminate global.cpp and do all definitions for global variables and functions inside the main or the file that uses them?
Declare and define the array vel within global.h. Maybe storing them within the same class would help.
My problem was that the Codeblocks IDE was not linking global.cpp. I found the answer here (first answer). I apologize if this question is a duplicate or combination of duplicates.
In a header file, I want to declare a short function
Rotate(array, degree), which would rotate an array of elements by some degree:
for example, if my array contains {1, 2, 3, 4, 5}, and the rotation degree is 2, then the modified array should be {4, 5, 1, 2, 3}.
My code is as follows:
#ifndef ROTATE_ARRAY_H
#define ROTATE_ARRAY_H
void Rotate(std::vector<int>& array, const int rotation_degree);
#endif // ROTATE_ARRAY_H
Now this short header file gives "expected primary expression before const"
on the line, where void is declared.
Note that if I remove vector from the function argument list, then
void Rotate(const int rotation_degree);
compiles successfully (but of course does not work as expected). So I believe, the problem is something to do with the vector.
Please bare in mind that this is a header file, and no code like
include<vector>;
using namespace std;
is allowed, as that would violate the style guide.
So the question is: how to get rid of "expected primary expression before const" error?
Thanks for your help in advance.
You need to rewrite (or simply throw out) your ridiculous style guide, and code:
#ifndef ROTATE_ARRAY_H
#define ROTATE_ARRAY_H
#include <vector>
void Rotate(std::vector<int>& array, const int rotation_degree);
#endif // ROTATE_ARRAY_H
it's not a question of style, that's how c++ works.
Since you are using std::vector, you need an #include <vector> before you have any code dealing with std::vector.
You have 2 choices here:
Either #include <vector> before you include your header file:
#include <vector>
#include "rotate_array.h"
int main(int argc, char *argv[]) {
std::vector<int> v = ... ;
rotate(v, 90);
}
Or include it in your headerfile, as any sane coding style would demand:
#ifndef ROTATE_ARRAY_H
#define ROTATE_ARRAY_H
#include <vector>
void Rotate(std::vector<int>& array, const int rotation_degree);
#endif // ROTATE_ARRAY_H
I have a problem with passing dynamically allocated structures to a function and accessing it's content.
The program uses mex to pass data from Matlab to C++. I use Visual Studio.
The structure I define in a header in 'InOut.h'
#include <string>
#include <cstdint>
#include <cstdlib>
struct sObjects {
std::string Type;
float *Position;
};
typedef struct sObject sObject;
In the main function I than allocate the structure is in 'MainFcn_Mex.cpp'
#include "MainFcn_Mex.h"
// ...
// get number of Objects from Matlab
int N_Obj = mxGetNumberOfElements(prhs[1]);
sObjects *Objects = new sObjects[N_Obj];
for (int k=0; k<N_Obj; k++) {
// get the pointer pointer map
pMap = mxGetField(prhs[1],k,"Type");
Objects[k].Type = mxArrayToString(pMap);
// get the pointer pointer map
pMap = mxGetField(prhs[1],k,"Position");
// setting pointer to the first Element
Objects[k].Position = (float*)mxGetPr(pMap);
mexPrintf("Objects(%d,1).Type: %s \n", k+1, Objects[k].Type);
}
create_Objects(Objects, N_Obj);
The function create_Objects is in a differente file 'create_Objects.cpp' and included via 'MainFcn_Mex.h':
#include <stdio.h>
#include <direct.h>
#define _USE_MATH_DEFINES
#include "math.h"
#include <cmath>
#include "mex.h"
#include "matrix.h"
#include <cuda.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include "InOut.h"
void create_Objects(sObjects *Objects, int N_Obj);
The content of 'create_Objects.cpp' so far is:
#define _USE_MATH_DEFINES
#include "math.h"
#include <cmath>
#include "InOut.h"
#include "mex.h"
void create_Objects(sObjects *Objects, int N_Obj)
{
for (int k=0; k<N_Obj; k++) {
mexPrintf("Objects(%d,1).Type: %s \n", k+1, Objects[k].Type);
}
}
Visual Studio tells me:
"error C2676: binary '[' : 'sObjects' does not define this operator or
a conversion to a type acceptable to the predefined operator"
Why can I access the data in the main function and not in seccondary functions?
How can I access a dynamically allocated structure in other functions, when its size isn't known at compile time?
Thanks a lot for your time!
It looks like you are trying to use struct directly as a typedef. Simply add typedef to your struct definition, will turn it into a type.
Like this:
... #include "mex.h"
typedef struct sObjects {
std::string Type;
float *Position;
};
(Otherwise you should use the full struct keyword as in void create_OpticsObjects(struct sObjects &Objects, int N_Obj).)
Your function prototypes don't need the extern qualifier.
You don't need extern unless you want globals variables. You seem to want simply global structs or types in your example, so extern is not required.
Using extern for globals
What you could be referring to is an instance of your object (or a pointer to your object), and that can be made global by using extern. as in this excerpt from the header file:
... #include "mex.h"
typedef struct sObjects {
std::string Type;
float *Position;
};
extern sObjects *pointerToOnesObjects;
Then in ONE source file, you need to declare the 'real' variable as in (this is good to initialise it here):
sObjects *pointerToOnesObjects = NULL;
With this method your variable pointerToOnesObjects is now available globally (in all your source files that use the same header file).
main.cpp
#include <vector>
#include <iostream>
#include "normal.h"
using namespace std;
int main()
{
return 0;
}
normal.h
#ifndef NORMAL_H
#define NORMAL_H
#include <vector>
#include <iostream>
using namespace std;
vector < int > myvector;
myvector.push_back(12);//does not name a type
#endif
I know I need to somehow include vector<int> myvector in main.cpp but can't figure the way. I've looked at my previous programs and didn't need to include anything in main.cpp.
The problem is that the code
myvector.push_back(12); is not inside any function. Outside of functions you may only declare (and possibly initialize) variables, you cannot put other code.
So, even though you can declare your vector in the .h file (probably to have it available in many files) you should move this line inside the main() or some other function.