C++: Accessing data of dynamic structures within extern function - c++

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).

Related

reference to 'list' is ambiguous including header file

When I add 'bits/stdc++.h'header file, it shows [Error] reference to 'list' is ambiguous. But when I erase the header and remain all other headers, the code is compiling properly.
#include <bits/stdc++.h>
#include<stdio.h>
#include <iostream>
#include<stdlib.h>
#include <string.h>
#include <sstream>
#define LIST_INIT_SIZE 2
#define NULL_VALUE -99999
#define SUCCESS_VALUE 99999
using namespace std;
int listMaxSize;
int * list;
int length;
void initializeList()
{
listMaxSize = LIST_INIT_SIZE;
list = (int*)malloc(sizeof(int)*listMaxSize) ;
length = 0 ;
}
Thats because the header <bits/stdc++.h> has its own version of list i.e. from the list template <list>.
Having two copies or different definitions of the same would result in ambiguity.
If its working without the bits header (STL) then simply dont use it.

Can't pass shared pointer as parameter to function definition?

If I place a function declaration with a shared pointer as a parameter and its definition in the header, everything compiles fine, but attempting to separate them into a .hpp and .cpp file causes compilation errors like:
Use of undeclared identifier 'std' //Solved via including <memory> & <cstdint>
Variable has incomplete type 'void' //Solved via including <memory> & <cstdint>
Use of undeclared identifier 'uint8_t' //Solved via including <memory> & <cstdint>
For example:
For this main: main.cpp
#include <iostream>
#include "example1.hpp" //Switch out with "example2.hpp"
int main(int argc, const char * argv[]) {
std::shared_ptr<uint8_t> image = 0;
foo(image);
return 0;
}
This Works:
example1.hpp
#ifndef example1_hpp
#define example1_hpp
#include <stdio.h>
void foo(std::shared_ptr<uint8_t> variable) { }
#endif /* example1_hpp */
This does not work:
example2.cpp
#include "example2.hpp"
void foo(std::shared_ptr<uint8_t> variable) { }
example2.hpp
#ifndef example2_hpp
#define example2_hpp
#include <stdio.h>
void foo(std::shared_ptr<uint8_t> variable);
#endif /* example2_hpp */
How do I separate the declaration and definition for this function into separate files successfully?
You have wrong includes. <stdio.h> is a C header. To use shared_ptr you need to include <memory>, to use uint8_t you need to include <cstdint>.

Undefined reference to global array

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.

Access Array in Library.cpp

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].

myvector does not name a type

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.