I am recently started reading about alsa api. I was trying to write a C++ class which opens default device and reads basic parameters like maximum rate, number of channels etc.
My class header file is:
#include <alsa/asoundlib.h>
#include <iostream>
class AlsaParam{
snd_pcm_t* pcm_handle;
snd_pcm_hw_params_t* hw_param;
....
public:
int pcm_open();
.....
};
Inside pcm_open()
int AlsaParam::pcm_open(){
int err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
if(err > -1)
std::cout << pcm_handle->name << std::endl; //Just to test if it works
return err;
}
I get following error:
error: invalid use of incomplete type ‘snd_pcm_t {aka struct _snd_pcm}’
std::cout << pcm_handle->name << std::endl;
^
In file included from /usr/include/alsa/asoundlib.h:54:0,
from alsa_param.h:4,
from alsa_param.cpp:1:
/usr/include/alsa/pcm.h:341:16: error: forward declaration of ‘snd_pcm_t {aka struct _snd_pcm}’
typedef struct _snd_pcm snd_pcm_t;
^
From this error I understood that asoundlib.h only uses typedef for struct snd_pcm_t but it is defined somewhere else. Am I correct? Is there any way to solve this problem? In general if we are including some c library functions in C++ class which are the things to remember/ avoid? Thanks
The layout of struct _snd_pcm is deliberately hidden from programs because it might change in a new library version.
To get a PCM device's name, call snd_pcm_name:
cout << snd_pcm_name(pcm_handle) << endl;
(Pretty much everything in ALSA needs such a function call.)
There is nothing wrong with your code. Just that there is missing declaration of struct _snd_pcm, the header you included only has the typedef: typedef struct _snd_pcm snd_pcm_t;
What you can do is look up (maybe on the internet or in the manual) for the header that hasstruct _snd_pcm declaration and include it in your code.
There are a few differences in declaration syntax between C and C++.
Since you're compiling a C++ file but including a C header inside it, you probably need to make the compiler interpret it the right way.
Try this:
extern "C"
{
#include <alsa/asoundlib.h>
}
#include <iostream>
class AlsaParam{
snd_pcm_t* pcm_handle;
snd_pcm_hw_params_t* hw_param;
...
Related
(Not sure whether this is exclusively a C/C++ issue)
I’m currently fragmenting elements of a large Arduino project into reusable libraries - so far soo good.
However, a number of methods in the libraries return special structs which are declared in a data-types.h file contained in each library. The problem I have now is I'm unable to import/utilise these structs in my main sketch. I've tried declaring a variable of the DataTypes class in the main library header file and accessing the structs through it, but I get error error: invalid use of 'struct DataTypes::_theStructNameHere_t'
How would I go about accessing these structs from the library in my main sketch to declare as a variable type? I don't want to have to copy the header file which contains the structs from the library into my sketch, and I also don't want to have to create a separate library just for this single header file of structs!
Here's a quick example of what I mean:
Main.cpp:
#include <Arduino.h>
#include <MyLibrary.h>
MyLibrary myLib;
void setup() {
(This is declared in the library) myLib.dataTypes._theStructNameHere_t response = myLib.getASpecialValueWhichIsOfType_theStructNameHere_t()// Gives "error: invalid use of 'struct DataTypes::_theStructNameHere_t'""
// Example usage of the struct:
Serial.print("\n Loop Card Status: ");Serial.print(response.loop_status, HEX);
if (response.number_allocated > 0) {
Serial.print("\n Devices Allocated: ");Serial.print(response.number_allocated, HEX);
} else {
if (response.loop_status != 0x123) {
// Some condition
} else {
// Something else
}
}
}
void loop() {
...
}
Library Structure:
src/
- /data-types/
- - data-types.h
- MyLibrary.cpp
- MyLibrary.h
Library Header MyLibrary.h:
#ifndef _MYLIBRARY_H_
#define _MYLIBRARY_H_
#include <Arduino.h>
#include "./helpers/helpers.h"
...
#include "./data-types/data-types.h"
class MyLibrary {
public:
Uart *_commPort;
Helpers helpers;
...
DataTypes dataTypes;
DataTypes::_theStructNameHere_t getASpecialValueWhichIsOfType_theStructNameHere_t();
...
protected:
private:
};
#endif // _MYLIBRARY_H_
DataTypes Class data-types.h:
#ifndef _RESPONSE_TYPES_H
#define _RESPONSE_TYPES_H
class DataTypes
{
public:
struct _theStructNameHere_t
{
bool successful;
uint8_t loop_status;
uint8_t number_allocated;
uint8_t highest_address;
uint8_t number_inputs;
uint8_t number_outputs;
}
..even more..
private:
}
#endif // _RESPONSE_TYPES_H
I was able to obtain a MCVE from your example:
class DataTypes
{
public:
struct _theStructNameHere_t
{
};
};
class Library
{
public:
DataTypes dataTypes;
DataTypes::_theStructNameHere_t getMyDataType();
};
int main(int argc, char *argv[])
{
Library myLib;
myLib.dataTypes._theStructNameHere_t response;
}
which gives a similar error as your code:
~$ g++ test.cpp
test.cpp: In function 'int main(int, char**)':
test.cpp:20:21: error: invalid use of 'struct DataTypes::_theStructNameHere_t'
myLib.dataTypes._theStructNameHere_t response;
The problem is that you use an instance to access the struct type/name. To fix it, replace
myLib.dataTypes._theStructNameHere_t response = ...;
with
DataTypes::_theStructNameHere_t response = ...;
Notes:
Instead of using classes to create separate namespaces, please consider using namespaces directly. This is a feature of C++ which is available under Arduino.
namespace Library {
namespace DataTypes {
struct _theStructNameHere_t
{
...
};
...
} /*** namespace Library::DataTypes ***/
} /*** namespace Library ***/
Please read StackOverflow guidelines concerning how to ask a good question, in particular the section about Mininimal, Complete and Verifiable Example.
Sooner or later someone will tell you that there is no such thing as C/C++; C is C and C++ is C++; Arduino lives in its own world, even if is based on C++. Thus, you might want to remove C and C++ tags from your question.
I just feel weird about how does that work ?
That my first time that I've ever seen that , two c++ files located in the same directory "Test1.cpp,Test2.cpp"
Test1.cpp :
#include <iostream>
void magic();
int main(){
magic();
return 0;
}
Test2.cpp :
#include <iostream>
using namespace std;
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
As I mentioned above , they are in the same directory , with prototype of 'magic' function.
Now my question is , how does magic work without any inclusion of Test2.cpp ?
Does C++ include it by default ? if that's true , then why do we need to include our classes ? why do we need header file while cpp file can does its purpose ?
In order to obtain an executable from a C++ source code two main phases are required:
compilation phase;
linking phase.
The first one searches only for the signature of the functions and check if the function call is compatible with the found declarations.
The second one searches the implementation of the function among the libraries or objects linked through the options specified through command line of the linker (some compilers can automatically run the linker adding some command line options).
So you need to understand the compiler and linker options in order to understand this process.
The main catch of headers file is simplifying writing of code.
Let's think about next example:
test2.cpp
#include <iostream>
using namespace std;
void my ()
{ magic(); } // here we don't know what magic() is and compiler will complain
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
This code gives next error:
gaal#linux-t420:~/Downloads> g++ test2.cpp
test2.cpp: In function ‘void my()’:
test2.cpp:6:9: error: ‘magic’ was not declared in this scope
{ magic(); } // here we don't know what magic() is and compiler will complain
^
To avoid this error we need to place declaration of magic() function before definition of my(). So it is good idea to place ALL declarations in one place. Header file is a such place. If we don't use headers, we'll need to paste declaration of magic() function in any cpp-file where it will be used.
I’m trying to pass a Structure from a Matlab function in Simulink to an external C++ function using the coder.ceval() and the coder.cstructname(). When I try to run the code on an Arduino Due board using the deploy to hardware tool in Simulink I get the error:
error: invalid use of incomplete type 'struct MyStruct'
error: forward declaration of 'struct MyStruct'
I’m using the example code from mathworks but use a c++ function instead of a c function:
Header use_struct.h:
#include <tmwtypes.h>
typedef struct MyStruct
{
double s1;
double s2;
} MyStruct;
void use_struct(struct MyStruct *my_struct);
C++ function use_struct.cpp:
#include <stdio.h>
#include <stdlib.h>
// #include "use_struct.h" // Doesn’t work when I include it here
extern “C” void use_struct(struct MyStruct *my_struct)
{
double x = my_struct->s1;
double y = my_struct->s2;
}
Matlab function:
structVar.s1 = 1;
structVar.s2 = 2;
if strcmp(coder.target,'rtw'),
coder.cinclude('use_struct.h');
coder.cstructname(structVar, 'MyStruct', 'extern');
coder.ceval('use_struct', coder.ref(structVar));
end
I need it to be a C++ function for the later code. However I also tried it with a c function without the extern “C” but it doesn’t work anyway. Can anyone help me with this problem?
I found the solution. I had to include the c header use_struct.h in the use_struct.cpp also with:
extern "C"
{
#include "use_struct.h"
}
The following sketch to fails to compile in the Arduino environment.
Given that typedefs can be used within Arduino software, is Automatic Prototype Generation the underlying mechanism that causes the failure? If so, what is it and why isn't Arduino providing a lightweight wrapper around C++?
#define PRODUCE_WACKY_COMPILETIME_ERROR
typedef int MyMeaningfulType;
#ifndef PRODUCE_WACKY_COMPILETIME_ERROR
void myFunc(MyMeaningfulType myParam);
#endif
void myFunc(MyMeaningfulType myParam)
{
myFunc(10);
}
void setup() {}
void loop() {}
For the benefit of the search engines, the errors reported are:
error: variable or field 'myFunc' declared void
error: 'MyMeaningfulType' was not declared in this scope
Please refer to http://arduino.cc/en/Hacking/BuildProcess the specific quote is:
This means that if you want to use a custom type as a function argument, you should declare it within a separate header file.
This page does a good job of explaining how the Arduino Language is different from C/C++ in how it works/pre-processes files.
They are attempting to create prototypes for every function they find. Unfortunately, if you define a typedef in the file before the function, and use that in a function definition, the place they put the function prototype does not see it, and this generates a syntax error.
If you use the 'struct * ' syntax instead in those function definitions, you benefit from C's 'opaque type' facility, in which you can use a struct definition without having it be declared beforehand. So, build the typedef, use it, but use the struct definition in any functions that use the typedef in arguments.
typedef struct mytype_ {
int f1;
} mytype_t;
void myfunc(struct mytype_ * xxx) {
xxx->f1 = 1;
}
The biggest problem I seem to run into when coding in c++ is the fact that you must declare a class before you can reference it. Say I have two header file like this...
Header1.h
#include "Header2.h"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage;
class Hello
{
public:
string Message;
HelloPackage * Package;
Hello():Message("")
{
}
Hello(string message, HelloPackage * pack)
{
Message = message;
Package = pack;
}
void Execute()
{
cout << Message << endl;
//HelloPackage->NothingReally doesn't exist.
//this is the issue essentially
Package->NothingReally(8);
}
};
Header2.h
#include "Header1.h"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage
{
public:
deque<Hello> Hellos;
HelloPackage()
{
Hellos = deque<Hello>();
}
int AddHello(string Message)
{
Hellos.push_back(Hello(Message,this));
}
void ExecuteAll()
{
for each(Hello h in Hellos)
h.Execute();
}
int NothingReally(int y)
{
int a = 0;
a += 1;
return a + y;
}
}
What I'm wondering is, is there any elegant solution for dealing with these issues? In say c#, and java, you're not restricted by this "linear" compiling.
Use header include guards, either "#ifndef / #define / #endif", or "#pragma once"
Put your code in a .cpp, not inline in the header
???
Profit
The reason this will work for you is because you can then use forward declarations of the class you want to reference without including the file if you so wish.
You are missing include guards
why define methods in the header?
Besides these problems with your code, to answer your question : normal way is to forward declare classes - not to include headers in headers (unless you have to).
If you follow a few basic rules, it is not awkward at all. But in comparison to e.g. Java or C#, you have to follow these rules by yourself, the compiler and/or language spec does not enforce it.
Other answers already noted that, but I will recap here so you have it in one place:
Use include guards. They make sure that your header (and thus your class definition) is only included once.
Normally, you will want to separate the declaration and implementation of your methods. This makes the header files more reusable and will reduce compilation time, because the header requires normally fewer #includes than the CPP (i.e. implementation) file.
In the header, use forward declarations instead of includes. This is possible only if you just use the name of the respective type, but don't need to know any "internals". The reason for this is that the forward declaration just tells the compiler that a certain name exists, but not what it contains.
This is a forward declaration of class Bar:
class Bar;
class Foo {
void foooh(Bar * b);
};
Here, the compiler will know that there is a Bar somewhere, but it does not know what members it has.
Use "using namespace xyz" only in CPP files, not in headers.
Allright, here comes your example code, modified to meet these rules. I only show the Hello class, the HelloPackage is to be separated into header and CPP file accordingly.
Hello.h (was Header1.h in your example)
#include <string>
class HelloPackage;
class Hello
{
public:
Hello();
Hello(std::string message, HelloPackage * pack);
void Execute();
private:
string Message;
HelloPackage * Package;
};
Hello.cpp
#include "Hello.h"
#include "HelloPackage.h"
using namespace std;
Hello::Hello() : Message("")
{}
Hello::Hello(string message, HelloPackage * pack)
{
Message = message;
Package = pack;
}
void Hello::Execute()
{
cout << Message << endl;
// Now accessing NothingReally works!
Package->NothingReally(8);
}
One question that may arise is why is the include for string is needed. Couldn't you just forward declare the string class, too?
The difference is that you use the string as embedded member, you don't use a pointer to string. This is ok, but it forces you to use #include, because the compiler must know how much space a string instance needs inside your Hello class.