I'm defining my structure in python according to the docs (or so I think) but when calling the c function the values don't match:
Python code:
print(f"SchemaID:{appHandResp.supportedAppProtocolRes.SchemaID}, SchemaID_isUsed:{appHandResp.supportedAppProtocolRes.SchemaID_isUsed}")
errn = openv2g.encode_appHandExiDocument(byref(oStream), byref(appHandResp))
C code:
int encode_appHandExiDocument(bitstream_t* stream, struct appHandEXIDocument* exiDoc) {
if (exiDoc->supportedAppProtocolRes_isUsed)
printf("SchemaID:%d, SchemaID_isUsed:%d\n", exiDoc->supportedAppProtocolRes.SchemaID, exiDoc->supportedAppProtocolRes.SchemaID_isUsed);
Output:
# in Python right before calling the C function
SchemaID:2, SchemaID_isUsed:1
# in the C function
SchemaID:1, SchemaID_isUsed:0
The structure definitons:
# Python3.8
appHandresponseCodeType = ctypes.c_uint8
appHandresponseCodeType_OK_SuccessfulNegotiation,\
appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation,\
appHandresponseCodeType_Failed_NoNegotiation = map(appHandresponseCodeType, range(3))
class appHandAnonType_supportedAppProtocolRes(ctypes.Structure):
_fields_ = [
("ResponseCode", appHandresponseCodeType),
("SchemaID", ctypes.c_uint8),
("SchemaID_isUsed", ctypes.c_uint, 1),
]
.
// C
typedef enum {
appHandresponseCodeType_OK_SuccessfulNegotiation = 0,
appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation = 1,
appHandresponseCodeType_Failed_NoNegotiation = 2
} appHandresponseCodeType;
struct appHandAnonType_supportedAppProtocolRes {
appHandresponseCodeType ResponseCode ;
uint8_t SchemaID ;
unsigned int SchemaID_isUsed:1;
};
Playing with the structure definition in python I was able to get the expected result:
appHandresponseCodeType = ctypes.c_uint
appHandresponseCodeType_OK_SuccessfulNegotiation,\
appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation,\
appHandresponseCodeType_Failed_NoNegotiation = map(appHandresponseCodeType, range(3))
class appHandAnonType_supportedAppProtocolRes(ctypes.Structure):
_fields_ = [
("ResponseCode", appHandresponseCodeType),
("SchemaID", ctypes.c_uint8),
("SchemaID_isUsed", ctypes.c_uint8),
]
Output:
# in Python right before calling the C function
SchemaID:2, SchemaID_isUsed:1
# in the C function
SchemaID:2, SchemaID_isUsed:1
I can't explain why this is the case, am I defining my structure in ctypes wrong?
Not 100%, but I think that this shows the underlying problem:
#include <stdio.h>
typedef struct A {
char x;
unsigned y:1;
} A;
int main() {
printf("%zu\n", sizeof(A));
return 0;
}
prints the value '4' using clang/macos/64bit, gcc/linux/64bit. It is because of the bitfield permitting the compiler to compact the structure.
This should work for you. A C enum is equivalent to a c_int. You don't need to cast the enum values. Just assign them to ResponseCode as needed. It is odd to use a bitfield for a single bit. That one bit will still occupy a full c_uint (typically 32-bits) anyway. There will also normally be three padding bytes between the c_uint8 and the next c_uint for alignment purposes, unless you also set _pack_ as well (must be before _fields_ if used). Check the C header for any packing directives.
from ctypes import *
appHandresponseCodeType_OK_SuccessfulNegotiation = 0
appHandresponseCodeType_OK_SuccessfulNegotiationWithMinorDeviation = 1
appHandresponseCodeType_Failed_NoNegotiation = 2
class appHandAnonType_supportedAppProtocolRes(Structure):
# _pack_ = 1 # if needed, uncomment.
_fields_ = (('ResponseCode',c_int),
('SchemaID',c_uint8),
('SchemaID_isUsed',c_uint,1))
Related
I have a large module that uses a very large input buffer, consisting of many structures which, in turn, contain other structures and in the end each structure has several variables.
Out of these hundreds of input variables, my module (standalone C entity) uses only a fraction.
I would like to know if there is a way to make a list that will contain only the variables used in my module (would be perfect if it contains the variable type and links to structure/s that contains it).
I tried Doxygen (1.8.5) but I could generate a doc with all input variables, only.
[Later EDIT]
I add an example code and the desired outcome:
#include <stdio.h>
typedef struct subS1{
unsigned char bIn1;
unsigned char bIn2;
} subS1;
typedef struct S1{
struct subS1 stMySubStruct1;
struct subS1 stMySubStruct2;
struct subS1 stMySubStruct3;
} MyInputStruct_t;
void Foo1(MyInputStruct_t *Input);
void Foo2(MyInputStruct_t *Input);
MyInputStruct_t stMyInputStruct = {{1, 2}, {0, 0}, {9, 6}}; // large input buffer
int main() {
Foo1(&stMyInputStruct); // call to my Module 'main' function
return 0;
}
void Foo1(MyInputStruct_t *Input)
{
if(Input->stMySubStruct1.bIn1 == 1)
{
printf("bIn1 = %d\n", Input->stMySubStruct1.bIn1); // stMySubStruct1.bIn1 is used (read or write)
}
Foo2(Input);
return;
}
void Foo2(MyInputStruct_t *Input)
{
if(Input->stMySubStruct3.bIn2 == 0)
{
printf("bIn2 = %d\n", Input->stMySubStruct3.bIn2); // stMySubStruct3.bIn2 is used (read or write)
}
return;
}
The list with just the used inputs for Foo1(): e.g
stMyInputStruct.stMySubStruct1.bIn1 -> is used in Foo1()
stMyInputStruct.stMySubStruct1.bIn2 -> is NOT used
...
stMyInputStruct.stMySubStruct3.bIn2 -> is used in Foo2()
This is just a five-minute hack to demonstrate what I mean, so take it with a grain of salt and for what it is.
So first I downloaded pycparser from https://github.com/eliben/pycparser/
Then I edit the C-generator from https://github.com/eliben/pycparser/blob/master/pycparser/c_generator.py
... adding two lines to the constructor-code (adding two vars struct_refs + struct_ref):
class CGenerator(object):
""" Uses the same visitor pattern as c_ast.NodeVisitor, but modified to
return a value from each visit method, using string accumulation in
generic_visit.
"""
def __init__(self, reduce_parentheses=False):
""" Constructs C-code generator
reduce_parentheses:
if True, eliminates needless parentheses on binary operators
"""
# Statements start with indentation of self.indent_level spaces, using
# the _make_indent method.
self.indent_level = 0
self.reduce_parentheses = reduce_parentheses
# newly added variables here
self.struct_refs = set()
self.struct_ref = None
Then I edit two visitor-functions, to make them save information about the struct-references they parse:
def visit_ID(self, n):
if self.struct_ref:
self.struct_refs.add(self.struct_ref + "->" + n.name)
return n.name
def visit_StructRef(self, n):
sref = self._parenthesize_unless_simple(n.name)
self.struct_ref = sref
self.struct_refs.add(sref)
res = sref + n.type + self.visit(n.field)
self.struct_ref = None
return res
Running this modified piece of Python script over your example code, collects this information:
>>> cgen.struct_refs
{'Input',
'Input->stMySubStruct1',
'Input->stMySubStruct1->bIn1',
'Input->stMySubStruct3',
'Input->stMySubStruct3->bIn2'}
So with a bit more work, it should be able to do the job more generally.
This of course breaks apart in the face of memcpy, struct-member-access-through-pointers etc.
You can also try exploiting structure in your code as well. E.g. If you always call your input-struct "Input", things gets easier.
I'm an avid embedded c programmer. I recently started working with the ESP IDF framework to program the ESP32. Even though I think that the following code is initializing a struct within a struct (not sure); but for some reason, I cannot grasp how and why there is just a ".mode" rather than the struct's name within gpio_config_t + ".mode". This is just an example but there are several instances of similar types of initialization.
for example:
typedef struct example_struct{
int mode;
int pull_up_en;
.
.
}example_struct;
typedef struct gpio_config_t
{
example_struct test;
} gpio_config_t;
Shouldn't the initialization be done the following way?
gpio_config_t io_test_config =
{
test.mode = 3;
test.pull_up_en = 1;
etc
};
Can someone please clarify this?
The actual type of initialization I'm referring to:
gpio_config_t io_conf = {
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = 1,
};
The technical term for the notation you're using is designated initializers. The designators always start with either a . or a [, and there are no semicolons in the initializers (until after the } at the end of the initializer). There are many ways that you could initialize that structure, including:
gpio_config_t io_test_config1 =
{
.test.mode = 3, .test.pull_up_en = 1
};
gpio_config_t io_test_config2 =
{
.test = { .mode = 3, .pull_up_en = 1 }
};
gpio_config_t io_test_config3 =
{
{ 3, 1 }
};
gpio_config_t io_test_config4 =
{
3, 1
};
The last one doesn't compile cleanly with GCC when you specify -Wmissing-braces (usually activated by -Wall).
Hi I am following the book Linux device driver development to write a driver in Linux. In an example code as below:
struct my_gpios {
int reset_gpio;
int led_gpio;
};
static struct my_gpiosneeded_gpios = {
.reset_gpio = 47;
.led_gpio = 41;
};
static struct resource needed_resources[] = {
[0] = { /* The first memory region */
.start = JZ4740_UDC_BASE_ADDR,
.end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
.flags = IORESOURCE_MEM,
.name = "mem1",
},
[1] = {
.start = JZ4740_UDC_BASE_ADDR2,Platform Device Drivers
[ 126 ]
.end = JZ4740_UDC_BASE_ADDR2 + 0x10000 -1,
.flags = IORESOURCE_MEM,
.name = "mem2",
},
};
static struct platform_devicemy_device = {
.name = "my-platform-device",
.id = 0,
.dev = {
.platform_data = &needed_gpios,
},
.resource = needed_resources,
.num_resources = ARRY_SIZE(needed_resources),
};
platform_device_register(&my_device);
I do not understand the syntax static struct_gpiosneeded_gpios = {} meaning and why have a dot in .reset_gpio. And what is the meaning of the syntax static struct [] = {[0]={}, [1]={}}?
Could you please give me a reference link or keyword or example about static struct {.a = VALUE, .b = VALUE,};?
static struct something x = {
.field_one = 123,
.field_two = 456
};
This is a struct initialization syntax, standard from C99 (see here). This example creates a variable of type struct something named x, with fields field_one and field_two initialized to the specified values, and any other field initialized to 0. The static keyword is a storage duration specifier (see here).
static struct something x[] = {[0]={ ... }, [1]={ ... }};
This is a mix of both struct initialization and array initialization syntax, again standard from C99 (see here). This example creates an array x of variables of type struct something, the one at index 0 is initialized with the contents of the {...} initializer, and the same goes for the one at index 1. Since the greatest specified index is 1, the array size is 2.
I do not understand why they named the type is u32 or what is the purpose of __raw.
The u32 type is just a short alias for uint32_t.
I am not sure exactly where you saw __raw, since I don't seem to find anything like it in the kernel source. In any case, the Linux kernel as a series of compile-time annotations used for variables that have different purposes (__user, __rcu, etc). Those are not part of the C standard and frequently not even GCC extensions. They are mostly hints to be used by Sparse, the Linux kernel semantic checker.
Is there any standard or rule for naming the variable, macro, type,... in kernel?
Refer to the Linux kernel coding style documentation page for more information. I would suggest you to read it all before trying to do any kind of kernel programming. The more documentation pages you read, the better.
And what C standard i have to compliance when writing code in linux driver?
Use anything that is C99 or older and you will be fine. The Linux kernel code does not adhere to a single C standard, and various parts of the code aren't even standard compliant, but use GCC extensions. See here for more information.
You don't usually choose the standard when compiling, the kernel Makefile does this for you, and it should default to C90.
In any case, those are a lot of questions. If you have a specific question I would suggest you to ask it separately so that people are able to give you a focused and more extensive answer, since it's off topic to ask too broad or too many questions.
I have a program which should adjust number of elements to number of devices it is working with. I have a config *.txt file that contains some parameters that allows users who don't know programming language to adjust program to their needs.
For example till now everything have been handled like this. In header file:
enum
{
// number of input and output channels
kMaxInputChannels = 8,
kMaxOutputChannels = 8
};
typedef struct AudioDriverSettings
{
(...)
ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels];
ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels];
(...)
} AudioDriverSettings;
typedef struct AudioFileConfig
{
(...)
int inputId[kMaxInputChannels];
int outputId[kMaxOutputChannels];
bool shouldMixInput[kMaxInputChannels];
bool shouldRecordChannel[kMaxInputChannels];
(...)
} AudioFileConfig;
In *.txt there are variables:
NUM_CHANNELS_IN 8
NUM_CHANNELS_OUT 8
And on program start I am reading it and writing to variable:
if (!strcmp(tmp_str, "NUM_CHANNELS_IN"))
NUM_CHANNELS_IN = atoi(token);
if (!strcmp(tmp_str, "NUM_CHANNELS_OUT"))
NUM_CHANNELS_OUT = atoi(token);
I would like to get effect as below but variable needs to be const so it isn't working.
int NUM_CHANNELS_IN;
int NUM_CHANNELS_OUT;
typedef struct AudioDriverSettings
{
(...)
ASIOBufferInfo bufferInfos[NUM_CHANNELS_IN + NUM_CHANNELS_OUT];
ASIOChannelInfo channelInfos[NUM_CHANNELS_IN + NUM_CHANNELS_OUT];
(...)
} AudioDriverSettings;
typedef struct AudioFileConfig
{
(...)
int inputId[NUM_CHANNELS_IN];
int outputId[NUM_CHANNELS_OUT];
bool shouldMixInput[NUM_CHANNELS_IN];
bool shouldRecordChannel[NUM_CHANNELS_IN];
(...)
} AudioFileConfig;
Is there any simple way to handle it?
If this is C, you need to allocate your arrays dynamically:
ASIOBufferInfo *bufferInfos;
...
bufferInfos = malloc(sizeof(ASIOBufferInfo) * (NUM_CHANNELS_IN + NUM_CHANNELS_OUT));
If this is C++, use the std::vector class:
std::vector<ASIOBufferInfo> bufferInfos;
...
bufferInfos.reserve(NUM_CHANNELS_IN + NUM_CHANNELS_OUT);
and then push_back to the vector. Or:
std::vector<ASIOBufferInfo> bufferInfos(NUM_CHANNELS_IN + NUM_CHANNELS_OUT);
and then just access the elements like bufferInfos.at(i).
I Believe the answer you are looking for is to use pointers. By changing from:
int NUM_CHANNELS_IN;
int NUM_CHANNELS_OUT;
to:
int *NUM_CHANNELS_IN;
int *NUM_CHANNELS_OUT;
You will be able to pass your variable out of functions etc. I cannot say the exact changes you will need to make to your code, you may need to brush up on the proper syntax for pointers, But i believe this is the simplest way to achieve what you are trying to do if I have correctly interpreted your question.
Hope this helps!
I'm trying to wrap my head around the syntax provided in http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7l.doc%2Flanguage%2Fref%2Fclrc03strin.htm :
struct
{
int a[5], b;
} game[] =
{
[0].a = { 1 },
[1].a[0] = 2
};
Ideally, I'd find some way to do the following:
struct
{
int a, b;
} foo =
{
.a = 4,
.b = 5
};
My reason for wanting to have a by-name initialization of a structure is that my own stucture has many members, so I want better clarity. I shouldn't just initialize them in separate statements because this is a performance-sensitive embedded application where the members are actually bitfields, so a single struct init generates fewer instructions than multiple member initializations.
Which C standard allows for by-name member init like that?
It's not immediately clear what you're asking, but with a c99 compiler, your first attempt could be written as
struct
{
int a[5], b;
} game[] =
{
[0] = {.a = { 1 }},
[1] = {.a[0] = 2}
};
I'm doing something similar in an embedded app under C99. I have a variable called phaseInstill that is "assigned" to a struct:
phaseInstill = (PhaseVolumeStatus)
{
.complete = false,
.ticksInstilled = 0,
.volumeInstilled = 0,
.volumeRemaining = instillVolume
};
Where PhaseVolumeStatus is defined as:
typedef struct
{
Value volumeRemaining; /*!> ml */
Value volumeInstilled; /*!> ml */
Value ticksInstilled; /*!> ticks */
bool complete;
} PhaseVolumeStatus;
I don't have a bitfield example handy, but I don't recall it working any differently in any other of my uses.