How can i use a Library for another Library ? [Arduino ESP32] [duplicate] - arduino-c++

This question already has answers here:
C++ Global variable declaration
(5 answers)
Closed 9 months ago.
I am working on a project on Arduino ESP32 and I have a lot of Global variables (for data generation). I have decided to create a library in order to orgenise my work a little better. But I use this library into other librari's that I had to create for other usage. after compilation it I have the following error :
sketch\OX2inj_LEVEL_OX2.cpp.o:(.data.addrChipId+0x0): multiple definition of `addrChipId'
sketch\First_Useage.cpp.o:(.data.addrChipId+0x0): first defined here
sketch\OX2inj_LEVEL_OX2.cpp.o:(.bss.ChipID+0x0): multiple definition of `ChipID'
sketch\First_Useage.cpp.o:(.bss.ChipID+0x0): first defined here
here is my .ino (main) code :
#include <Arduino.h>
#include "Var_Str_EEPROM.h"
#include "Def_Global_Var.h"
#include "First_Useage.h"
//---------somthing
void setup()
{
Serial.begin(115200);
//---------somthing
Serial.println(ChipID.ReadStrEEPROM());
//---------somthing
}
void loop()
{
//---------somthing
}
here is my "Def_Global_Var.h" code
#ifndef Def_Global_Var_H
#define Def_Global_Var_H
#include "Var_Str_EEPROM.h"
uint16_t addrChipId = 1;
VarStrEEPROM ChipID(addrChipId);
#endif
here is my "First_Useage.h" code
#ifndef First_Usage_H
#define First_Usage_H
void getchipid();
#endif
here is my "First_Useage.cpp" code :
#include "First_Useage.h"
#include <Arduino.h>
#include "Var_Str_EEPROM.h"
#include "Def_Global_Var.h"
void getchipid()
{
uint32_t chipId = 0;
for(int i=0; i<17; i=i+8)
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
ChipID.WriteStrEEPROM(String(chipId));
}
My understanding is that, when I use the #include "Def_Global_Var.h", the programme thinks that : "I am calling the library" and it sees that it has been called before and it does not like it.
Is it somehow correct ? and if it is(or not) correct what should I do?
EDIT : sorry I have put the wrong part of the prog. it has been corrected now

The actual cause is that the header is included into several source files, so you end up with multiple conflicting definitions of these variables in your .o files.
You shouldn't normally define global variables in header files at all; you should only declare them as extern:
#ifndef Def_Global_Var_H
#define Def_Global_Var_H
...
extern uint16_t addrChipId;
...
#endif
The second step is to define the variable in the corresponding .cpp file, this time without the extern keyword:
// Def_Global_Var.cpp
uint16_t addrChipId = 1;
Since Def_Global_Var.o gets linked only once, there should be no more conflicts.

Related

How to call upon a .dll file from C++ and extract the functions of it?

I would like to know the proper procedure for calling a .dll file with also having a .cpp and .h files for a certain application. I have a program which is the .cpp file with different .h header files and I also included the .dll file into the folder where the .cpp and .h files are located. I would like to know in the .cpp code how am I able to call upon this .dll file since inside of it there are different functions that will allow a DDC264 Evaluation Board to read data from memory through usb and extract the data. I am using a program called DevC++ and I am receiving a current Error which is [Id] returned 1 exit status and MakefileWin has changed.
Attached below is a snippit of the .cpp code:
I also would like to know how to fix both of these errors .enter image description hereenter image description here
// USB_IO_for_VB6.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "USB_IO_For_VB6.h"
#include "CyAPI.h"
#include <cstring>
#include <malloc.h>
#include "BASETSD.H"
#include <math.h>
#include <stdio.h>
// #include <string.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
//int USB_IO_FOR_VB6_EXPORTS int USB_IO_for_VB6_API =22;
I
USB_IO_FOR_VB6_API int nUSB_IO_for_VB6 = 22;
#define STRINGLEN 65536 //the larger this number is, the faster the data is shifted in.
#define MAX_CHANNELS_FAST 4096 // 2048= 1024A + 1024B
#define DBP 0 //debug print - 1 enables writing some information to a file in "C:\temp\"
// This function reads the device descriptors from the Cypress USB Chip(s).
// It returns arrays of values, one set of values per device detected.
// The user can then use the visual basic software to select which device to use.
int __stdcall ReadDeviceDescriptors(int *USBdevCount, int *bLengthPass, int *bDescriptorTypePass,
long *bcdUSBPass, int *bDeviceClassPass, int *bDeviceSubClassPass,
int *bDeviceProtocolPass, int *bMaxPacketSize0Pass, long *idVendorPass,
long *idProductPass, long *bcdDevicePass, int *iManufacturerPass,
int *iProductPass, int *iSerialNumberPass, int *bNumConfigurationsPass)
{
CCyUSBDevice *USBDevice;
USB_DEVICE_DESCRIPTOR descr;
USBDevice = new CCyUSBDevice(NULL); // Create an instance of CCyUSBDevice
USBdevCount[0] = USBDevice->DeviceCount();
for (int i=0; i < USBDevice->DeviceCount(); i++)
{
if (USBDevice->Open(i))
{
USBDevice->GetDeviceDescriptor(&descr);
bLengthPass[i]=descr.bLength;
bDescriptorTypePass[i]=descr.bDescriptorType;
bcdUSBPass[i]=descr.bcdUSB;
bDeviceClassPass[i]=descr.bDeviceClass;
bDeviceSubClassPass[i]=descr.bDeviceSubClass;
bDeviceProtocolPass[i]=descr.bDeviceProtocol;
bMaxPacketSize0Pass[i]=descr.bMaxPacketSize0;
idVendorPass[i]=descr.idVendor;
idProductPass[i]=descr.idProduct;
bcdDevicePass[i]=descr.bcdDevice;
iManufacturerPass[i]=descr.iManufacturer;
iProductPass[i]=descr.iProduct;
iSerialNumberPass[i]=descr.iSerialNumber;
bNumConfigurationsPass[i]=descr.bNumConfigurations;
USBDevice->Close();
}
}
return( USBdevCount[0] );
}
I am not sure about how to go about calling a .dll file in C++, I am fairly new to Object Oriented programming.
Regarding the MakefileWin error I tried changing the TDM-GCC release version from 32 to 64 bits and the error continues.
I also tried deleting the dllmain.cpp which is another cpp file that is not needed and moving another original.cpp file from the folder that is shown in one of the images.
I only have a single .cpp file running on my DevC++ compiler which I thought would not cause the Error [Id] returned 1 to exit status to pop up.

Static declaration of '__vector_1' follows non-static declaration

Im trying to create a program which will interrupt when I press the button. I have Atmega8 and I use Microchip studio for coding.
I checked the document about interrupts on atmega's website however I can't say I totally got it.
Here is my code:
#define F_CPU 1000000UL
#define IRQ1 INT0_vect
#define IRQ2 INT1_vect
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
void init()
{
DDRB=0b11111111;
PORTB=255;
_delay_ms(2000);
PORTB=0;
DDRD = 0b00000000;
GICR=0xc0;
MCUCR=0x08;
}
int main(void){
init();
volatile int mode = 0;
ISR(IRQ1){
_delay_ms(500);
if (mode<3)mode++; else mode = 0;
}
ISR(IRQ2){
_delay_ms(150);
}
}
Errors I get:
Imgur
I would be glad if any admin edits my question and add picture here, website doesn't let me add photo because I need at least 10 reputation to post image
Don't try to define functions inside of other functions unless you really know what you are doing. You should move the ISR definitions to the top level of the file, putting them outside of main.

AWSSDKCPP S3Client.GetObject

Having issues with GetObject. Intellisense in Visual Studio keeps evaluating the method as GetObjectW
...
unresolved external symbol "__declspec(dllimport) public: virtual class Aws::Utils::Outcome<class Aws::S3::Model::GetObjectResult,class Aws::Client::AWSError > __cdecl Aws::S3::S3Client::GetObjectW(class Aws::S3::Model::GetObjectRequest const &)const " (_imp?GetObjectW#S3Client#S3#Aws##UEBA?AV?$Outcome#VGetObjectResult#Model#S3#Aws##V?$AWSError#W4S3Errors#S3#Aws###Client#4##Utils#3#AEBVGetObjectRequest#Model#23##Z)
Here are my includes
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <aws/s3/model/DeleteObjectRequest.h>
#include <aws/s3/model/GetBucketLocationRequest.h>
#include <aws/s3/model/ListObjectsRequest.h>
All other methods work. Put works, Delete Works, Lists work. it all works. the projects are set to VS 2017. I am ONLY having problems with GetObject and as I said intellisense sees every other method except GetObject which it evaluates to GetObjectW
Client::ClientConfiguration config;
config.region = Region::US_EAST_2;
config.scheme = Http::Scheme::HTTPS;
config.connectTimeoutMs = 30000;
config.requestTimeoutMs = 30000;
S3Client s3Client(Auth::AWSCredentials(ACCESS_KEY, SECRET_KEY), config);
GetObjectRequest getObjectRequest;
getObjectRequest.WithBucket(bucket)
.WithKey(fileKey);
// //GetObject is Having issues here where it is not being found in referenced assembly it keeps being called GetObjectW...
// //It is perhaps the case there is a missing required reference for the method?
GetObjectOutcome getObjectOutcome = s3Client.GetObject(getObjectRequest);
resolved on https://github.com/aws/aws-sdk-cpp/issues/625
answer is:
must #undef GetObject before aws includes as follows:
#undef GetObject
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/GetObjectRequest.h>
This is a conflict with Windows.h

How to use stringstream in Xilinx SDK?

When trying to add
#include <sstream>
which is needed for stringstream, I get several errors, the following included:
expected ';' at end of input
expected '}' at end of input
macro "str" requires 2 arguments, but only 1 given
How to enable using stringstream ?
This is a bug in the Xilinx SDK.
You need to undef a macro named str.
Replace
#include <sstream>
with
#undef str
#include <sstream>
Credit:
This method was proposed by sparks333 and can be found here:
https://forums.xilinx.com/t5/Embedded-Development-Tools/Error-with-Standard-Libaries-in-Zynq/td-p/450032
I just signed up just to answer this question.
I went through this post some time ago and used the solution posed, even though I didn't like it very much. It was a mistake.
This solution can cause deadlock of the system after some time in a random way, very difficult to debug.
I propose the following solution:
create the file "compatible_sstream.h":
#pragma push_macro("str")
#undef str
#include <sstream>
#pragma pop_macro("str")
replace #include <sstream> with #include "compatible_sstream.h" in
all the other files.
wrap all calls to std::ostringstream::str in parentheses as in the example:
std::ostringstream foo()
{
// ...
}
void main()
{
// ...
std::cout << (foo().str)() << std::endl;
// ...
}
Apologies in advance if I have not followed any of the posting rules correctly.

C++ static initialization of pointers/references between translation units

First off, I have scoured stack overflow and the rest of the web and I am well aware of the following:
1) Global variables are Bad
2) Global variables dependencies between translation units is bad
However, we are using some middleware that is doing the following; and I can not ascertain whether this is dangerous.
// Global_Variable.hpp
#include "Type.hpp" /* this defines the type as a structure, doesn't really matter :) */
extern Type Global_Variable;
// Global_Variable.cpp
#include "Global_Variable.hpp"
Type Global_Variable = { /* init the struct */ };
// Global_Reference.hpp
#include "Type.hpp"
extern Type & Global_Reference;
// Global_Reference.cpp
#include "Global_Reference.hpp"
#include "Global_Variable.hpp"
Type & Global_Reference = Global_Variable; // does this suffer from the SIOF?
// Global_Pointer.hpp
#include "Type.hpp"
extern Type * Global_Pointer
// Global_Reference.cpp
#include "Global_Pointer.hpp"
#include "Global_Variable.hpp"
Type * Global_Variable = &Global_Variable; // does this suffer from the SIOF?
I am worried that Global_Variable and Global_Reference could be initialized to null rather than Global_Variable, can this be the case?
Thanks!