typedef struct BO2Offsets
{
struct Prestige
{
u32 offset = 0x000000;
char data[13] = { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C
};
};
} BO2Offsets;
This is a very amateur question with what I'm sure is going to be a very simple answer, but I can't resolve the problem. I have a .h file with his corresponding .cpp file, but for some reason whenever I try to compile with gcc, I keep getting errors:
declaration does not declare anything // line 10
expected ':', ',', ';', '}' or 'attribute' before '=' token // line 5
I would like use BO2Offsets like that:
BO2Offsets BO2;
BO2.Prestige.offset;
EDIT2:
Resolved, thank's :)
typedef struct BO2Offsets BO2Offsets;
struct BO2Offsets
{
struct Prestige
{
u32 offset;
char data[13];
} prestige;
};
You are probably using C compiler, but the code is C++ (that too C++14). You need to change the compiler (or toolset), or change the code so that it compiles with C compiler.
EDIT: Which line? Does it say struct Prestige is not utilized?
Based on your edit:
typedef struct Prestige
{
u32 offset = 0x000000;
char data[13] = { 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C
};
} prestige; // Small letters
...
BO2Offsets BO2;
BO2.prestige.offset;
I've used small letters for the variable, so that it is clearly different from the type Prestige.
Related
In the following project, the necessary parameters to initialize test.c are arranged in the structure DataStructure (Here I have only a pointer U8* Buffer). During init, the pointer Buffer is initialized (is pointed to an array) and the function test_init passes the initData to test.c. In test.c the content of the array is printed.
main.c
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
void init(DataStructure *pSL);
void main(void);
void main(void) {
DataStructure initData[COUNT];
init(&initData[0]);
test_init(&initData[0]);
test_run();
}
void init(DataStructure *pSL)
{
U8 Buffer[8] = {0xF1 , 0xF2 , 0xF3 , 0xF4 , 0xF5 , 0xF6 , 0xF7 , 0xF8};
DataStructure SL;
U8* pC = &Buffer[0];
SL.Buffer = pC;
*pSL = SL;
}
where test.c and test.h are:
#ifndef TEST_H_
#define TEST_H_
#ifndef U8
typedef unsigned char U8;
#endif
typedef struct{
U8 *Buffer;
} DataStructure;
#define COUNT 1
void test_init (DataStructure *List);
void test_run ();
#endif /* TEST_H_ */
and
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
static DataStructure *pD;
void test_init (DataStructure *_pD)
{
pD = _pD;
printf("\n test_init: ");
for(int i=0;i<8;i++)
printf("0x%0x, ",*(pD->Buffer+i));
}
void test_run (void)
{
printf("\n test_run: ");
for(int i=0;i<8;i++)
printf("0x%0x, ",*(pD->Buffer+i));
}
The output of this code is:
test_init: 0x0, 0x0, 0x0, 0x0, 0xf5, 0xf6, 0xf7, 0xf8,
test_run: 0x0, 0x0, 0x0, 0x0, 0xf5, 0xf6, 0xf7, 0xf8,
which is wrong. But if I print the elements of SL.Buffer within init function as well, i.e if I change the init function as follows:
void init(DataStructure *pSL)
{
U8 Buffer[8] = {0xF1 , 0xF2 , 0xF3 , 0xF4 , 0xF5 , 0xF6 , 0xF7 , 0xF8};
DataStructure SL;
U8* pC = &Buffer[0];
SL.Buffer = pC;
*pSL = SL;
printf("\n main: ");
for(int i=0;i<8;i++)
printf("0x%0x, ",*(SL.Buffer+i));
}
, the array is passed correctly:
main: 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
test_init: 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
test_run: 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
Could anybody explain me whats wrong whit this code and why the problem is fixed just by printing the array in init function?
And is it the right way to initialize and pass a structure containing a pointer?
The code is a simple version of my project. Originaly the DataStructure contains more parameters and the parameter COUNT (size of initData is more than one.
The problem, as I see it is with the usage of Buffer array.
It is local to the init() function, yet you return the address of the first element of the array to be used outside the function, where the array does not exist anymore. Hence, the address is essentially invalid and any attempt to access that memory will cause undefined behavior.
In the second case, it works fine, as you're printing the array before it ceases it's lifetime, so you're getting expected result.
Solution: You need to allocate static storage to the Buffer array, or use memory allocator function so as, the lifetime of the memory supersede the function scope.
When I run the following code
#include <stdio.h>
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
const uint8_t Symbols[] = {
0xCA,0x04,// size
0x0B, // width
0x0B, // height
0x00, // first char
0x04, // char count
0x01, 0x02, 0x03, 0x04,// char widths
// font data
0x00, 0x00, 0x20, 0x00, 0xF0, 0x07, 0x08, 0x04, 0x84, 0x07, 0x84, 0x07, 0x84, 0x07, 0x0E, 0x04, 0xF0, 0x07, 0x20, 0x00, 0x00, 0x00, // 0
0x10, 0x01, 0x08, 0x01, 0x04, 0x01, 0x04, 0x01, 0x08, 0x01, 0x10, 0x01, 0x10, 0x01, 0x08, 0x01, 0x04, 0x01, 0x04, 0x01, 0x00, 0x00, // 1
0x18, 0x00, 0xFF, 0x07, 0x18, 0x00, 0x00, 0x00, 0x80, 0x01, 0xFF, 0x07, 0x80, 0x01, 0x00, 0x00, 0x0C, 0x00, 0xFF, 0x07, 0x0C, 0x00, // 2
0x00, 0x02, 0x80, 0x05, 0x60, 0x04, 0x18, 0x04, 0x04, 0x04, 0x72, 0x05, 0x04, 0x04, 0x18, 0x04, 0x60, 0x04, 0x80, 0x05, 0x00, 0x02 // 3
};
typedef struct
{
uint16_t size; //2
uint8_t width; //1
uint8_t height; //1
uint8_t first_char; //1
uint8_t char_count; //1
uint8_t *font_widths;
uint8_t *font_data;
} _graphics_font;
_graphics_font* test;
uint8_t* font_st;
uint8_t temp;
int main(void)
{
test = (_graphics_font*)&Symbols;
font_st = (uint8_t*)&test->font_widths;
temp = font_st[0]+font_st[1]+font_st[2]+font_st[3]; //1+2+3+4 = 10
printf("temp=%d",temp);
return 0;
}
in C, I'm expecting that the pointer font_st will point exactly after the 6-th Byte of the Symbols array. Therefore the result printed should be 10. Instead of that the pointer is allocated to the 9-th byte, missing every time 2 bytes and wrongly to my expectations is printing 7 as a result. Why and how could that be?
Important update is that the using instead the line:
temp = font_st[-2]+font_st[-1]+font_st[0]+font_st[1]; //1+2+3+4 = 10
works.
This behaviour is most likely caused by struct padding.
Try the following:
#include <stdio.h>
#pragma pack(push, 1)
.... (all other code)
#pragma pack(pop)
As to the location of single elements in a struct, read about padding and packing, e.g. Structure padding and packing.
You could try it like this:
typedef struct glyph {
uint8_t char_width;
uint8_t[] glyph_data;
} glyph_t;
typedef struct font_t {
uint16_t size; //2
uint8_t width; //1
...
glyph_t[] glyphs;
} font_t;
That way, you can avoid some issues you are facing due to the dynamic addresses of the data, i.e. those which depend on the value of char_count.
Of course, if the size of glyph_data is not a constant, you have to provide your own access logic, like
uint8_t* p_glyph = (uint8_t*)(font->glyph_data[0]);
for ( int i = 0; i < requiredCharIndex; i++ ) {
p_glyph += total_size_of_glyph_in_bytes( (glyph_t*)p_glyph );
}
glyph_t* result = (glyph_t*)p_glyph;
test = (_graphics_font*)Symbols;
font_st = (uint8_t*)test->font_widths;
I didn't check that, but at simple sight I would say that &s was wrong in that context. Symbols and test are already pointers, so you are referencing to the address to that pointers.
You are not initializing correctly the two pointers in your struct.
test = (_graphics_font*)&Symbols;
On this line you are copying byte by byte from Symbols to test, which means that font_widths will point to the address made up by combining 0x01, 0x02, 0x03, 0x04, which contains garbage data.
Why 4 bytes? because every pointer in C has a size of 4 bytes regardless of the data it is pointing to.
Moreover, font_data will have the same behaviour.
Solution:
You have to use memcpy:
test->font_widths = (uint8_t*)memcpy(test->font_widths, Symbols + 6, 4*sizeof(uint8_t));
The same goes for font_data.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I know that people usually define macro with a single value, such as:
#define PIN0 0x01
but what does it mean by this one with multiple values?
#define POWER_UP 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
Supposedly, I need to send the packets 0x02, 0x01, 0x00.... sequentially. If not using this macro, I will probably use an array. However, the toolchain generate this macro to me but I don't know how to use this to send the packets. It doesn't look like the array definition of macro. Does anyone know how I shall use this?
Not really sure what you're asking about the packets (some more code would help) but:
char vals[] = { POWER_UP };
size_t i;
for (i = 0; i < sizeof(vals); ++i) {
/* do something with vals[i] */
}
//test.c
#define POWER_UP 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
POWER_UP
#only preprocessing
>gcc -E test.c
# 1 "test.c"
# 1 "<command-line>"
# 1 "test.c"
0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
As you can see it will replace the macro will your list of values.
It simply expands to 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80 whenever the POWER_UP macro is referenced.
my USART is receiving a string from a "black box" and the string contains two doubles and few hex values. The string is placed in my buffer rbuf.buf with a total size of 32 characters. Normally I receive 19 characters but few times extra erroneous characters at the end. The buffer typically looks like this (in hex):
0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x20, 0x36, 0x37, 0x2e, 0x38, 0x39, 0x20, 0x37, 0x41, 0x41, 0x20, 0x0a, 0x0d, 0x00, ...
I want to extract the two doubles 123.45 and 67.89 and have among several other examples tried following:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
...
void buffer_to_float(void)
{
static char string1[10] = "";
char *string2;
for(uint8_t i=0;i<6;i++)
{
char c = rbuf.buf[i]; // this is a char but how do I make it a pointer?
string2 = strcat ( string1, c ); // ... "char" is incompatible with "char*" ...
}
double R = atof(string2);
printf("%lf\n", R);
}
I know I'm doing something silly here but what?
I use an interrupt routine for receiving the string, should I do the extraction there or should this routine be as short/quick as possible?
Thanks for telling me how silly I am, I think I need it ;-)
You can use the sscanf function to read your two float values:
char bla[] = {0x31, 0x32, 0x33, 0x2e,
0x34, 0x35, 0x20, 0x36,
0x37, 0x2e, 0x38, 0x39,
0x20, 0x37, 0x41, 0x41,
0x20, 0x0a, 0x0d, 0x00};
float a, b;
sscanf(bla, "%f %f", &a, &b);
printf("%f %f\n", a, b);
I am getting an error message "expression must have constant value" when initializing an array of structures with an external constant integer.
File1.c:
const unsigned char data1[] =
{
0x65, 0xF0, 0xA8, 0x5F, 0x5F,
0x5F, 0x5F, 0x31, 0x32, 0x2E,
0x31, 0xF1, 0x63, 0x4D, 0x43,
0x52, 0x45, 0x41, 0x54, 0x45,
0x44, 0x20, 0x42, 0x59, 0x3A,
0x20, 0x69, 0x73, 0x70, 0x56,
// ...
};
const unsigned int data1_size = sizeof(data1);
File2.c:
const unsigned char data2[] =
{
0x20, 0x44, 0x61, 0x74, 0x61,
0x20, 0x52, 0x6F, 0x77, 0x20,
0x3D, 0x20, 0x34, 0x38, 0x12,
//...
};
const unsigned int data2_size = sizeof(data2);
Get_Byte.c:
extern const unsigned char * data1;
extern const unsigned int data1_size;
extern const unsigned char * data2;
extern const unsigned int data2_size;
struct Array_Attributes
{
const unsigned char * p_data;
const unsigned int size;
};
const struct Array_Attributes Data_Arrays[] =
{
{data1, data1_size}, // Error message is for data1_size here.
{data2, data2_size}, // Another error message generated for data2_size here.
};
I have also removed the const qualifier from the size field of Array_Attributes and get the same error message.
Why is the compiler complaining about a constant value expression when data1_size and data2_size are const unsigned int but in a different translation unit?
I want a constant array of [array address, array size] which is generated at compile time.
I am using Green Hills ccarm 4.24, on Windows XP, C language NOT C++.
C's const qualifier has little to do with what the compiler considers a constant expression, in this case. In an initializer, ie
const struct attributes attrs[] = {
{ expr1, expr2 },
...
}
expr1 and expr2 must have very specific forms to be acceptable to the compiler. The upshot of these restrictions is that the expressions can be evaluated without fetching from program variables, since these aren't in existence at compilation.
You're attempting to use data1_size and data2_size, which are not compile time constants by these rules.
By the way, the declarations
const unsigned char data1[] = { ... };
and
extern const unsigned char *data1;
are not compatible and will lead to a bug in your code. The latter should be
extern const unsigned char data1[];