Returning structs inside a class - class

I am converting my application to an OOP type but I am having problem with helper functions. What I did was place helper functions inside the class as private. How should I declare a function "addSection" to return a struct
This is for my .cpp file
section_t XIniFile::*addSection(ini_file_t *n, char *d)
{
section_t *s = (section_t *)malloc(sizeof(section_t *);
//add sections
return s;
}
This is for my .h file
class XIniFile
{
public:
int open(const char *);
int readString(const char *, const char *, char *);
int readInt(const char *, const char *, int *);
int writeString(const char *, const char *, char *);
int writeInt(const char *, const char *, int *);
int close();
private:
typedef struct key_tag {
char *name;
char *value;
key_tag *next;
} key_tag_t;
typedef struct sections_tag {
char *name;
sections_tag *next;
key_tag_t *keys;
} section_t;
typedef struct {
char *name;
section_t *sections;
int modified;
} ini_file_t;
section_t *add_section(ini_file_t *, char *);
key_tag_t *add_key(section_t *, char *, char *);
};
There are a lot of errors but I would like to start first from the first error which is error: ‘section_t’ does not name a type

turn add_section into:
XIniFile::section_t * XIniFile::add_section(ini_file_t *n, char *d)
since section_t is a member of XIniFile

Your struct section_t and other structs need to be declared above the functions that use them, like add_section. C++ type declarations are forward visible, meaning their visibility extend from the point they are first declared onward, but not behind. Order matters, it is an inherited trait of the C language, based on "textual" treatment of include files as opposed to true modules or multi file type metadata, where the compiler traditionally notes each type as it is declared syntactically, stores it in a symbol table, where it is immediately available.
This differs from Java or C# compilers which parse the whole source file first, then resolve types and symbols later, removing order from the equation.
Another error, your * is in the wrong place, move it to directly after section_t:
section_t XIniFile::*addSection(ini_file_t *n, char *d)
Change to:
XIniFile::section_t* XIniFile::addSection(ini_file_t *n, char *d)
Also, in C++ you don't have to use typedef for structs as in C. You can simply say:
struct key_tag_t {
char *name;
char *value;
key_tag_t *next;
};
struct section_t {
char *name;
sections_tag *next;
key_tag_t *keys;
};
section_t *add_section(ini_file_t *, char *);
key_tag_t *add_key(section_t *, char *, char *);
structs and classes are implicitly "typedefed" in C++, though there is a minor difference, it isn't relevant.

Related

Conversion in swift (id)initWithPreset:(int [])preset

Can u convert - (id)initWithPreset:(int [])preset;
in Swift
int *type = nil;
if (_selectedIndex == 0) {
type = PRESET_PHONE;
}
extern int PRESET_FM[];
extern int PRESET_CD[];
extern int PRESET_STUDIO[];
extern int PRESET_VOICE[];
extern int PRESET_PHONE[];
extern int PRESET_TAPE[];
extern int PRESET_HIFI[];
In Objective c
MP3Converter *mp3Converter = [[MP3Converter alloc] initWithPreset:type];
But I am using in Swift
var mp3Converter : MP3Converter!
mp3Converter = MP3Converter(preset:PRESET_VOICE )
How we give there preset:PRESET_VOICE?. It gives the error Unsafe Immutable Pointer..
The problem seems to be the way you have defined the constant arrays.
You will need to define them as integer pointers, than arrays. Check:
//const int PRESET_FM[] = {1, 2, 4, 5}; //<< This won't get exported to swift
const int * PRESET_FM = {1, 2, 4, 5}; //Swift can see this fine
And in your swift code, you will need to properly typecast this C constant to UnsafeMutablePointer as Swift will see the C pointers so.
var mp3Converter : mp3Converter = MP3Converter(preset:UnsafeMutablePointer<Int32>( PRESET_FM)(PRESET_VOICE))
Also ensure the objective C interface to use int * than int[]:
- (id)initWithPreset:(int *)preset
HTH.

Calling C++ from Swift - what is the equivalent of std::vector<T>

I'm calling a C++ function from Swift via a bridging header following SwiftArchitect's example. The signature for the C++ function is this:
long GrabberInitializeAndProcess(
unsigned char* pbInPixels,
int inStride,
unsigned char* pbOutPixels,
int outStride,
int width,
int height,
Point mqTopLeft,
Size mqSize,
std::vector<PolylineElement> * pForegroundMarks,
std::vector<PolylineElement> * pBackgroundMarks,
void* pGrabberState );
(N.B. Point, Size, and PolylineElement are local C++ structs.) What signature do I use in my Objective-C++ wrapper for std::vector<T>?
You are using vector as pointer. It's very good when you need use it in Swift.
You can use void* instead:
long GrabberInitializeAndProcess(
unsigned char* pbInPixels,
int inStride,
unsigned char* pbOutPixels,
int outStride,
int width,
int height,
Point mqTopLeft,
Size mqSize,
void * pForegroundMarks,
void * pBackgroundMarks,
void* pGrabberState );
And perform typecasting in implementation.
Or if you need type safety, you can white:
typedef struct _vectorOfPolylineElement *vectorOfPolylineElementPtr;
long GrabberInitializeAndProcess(
unsigned char* pbInPixels,
int inStride,
unsigned char* pbOutPixels,
int outStride,
int width,
int height,
Point mqTopLeft,
Size mqSize,
vectorOfPolylineElementPtr pForegroundMarks,
vectorOfPolylineElementPtr pBackgroundMarks,
void* pGrabberState );
And in implementation:
typedef struct _vectorOfPolylineElement
{
std::vector<PolylineElement> val;
} *vectorOfPolylineElementPtr;
And if you actually don't need vector in GrabberInitializeAndProcess, just it elements you can work with memory:
long GrabberInitializeAndProcess(
unsigned char* pbInPixels,
int inStride,
unsigned char* pbOutPixels,
int outStride,
int width,
int height,
Point mqTopLeft,
Size mqSize,
PolylineElement * pForegroundMarks,
size_t foregroundMarksCount,
PolylineElement * pBackgroundMarks,
size_t backgroundMarksCount,
void* pGrabberState );

MATLAB input struct with unsigned char into MEX file

I tried to input this struct from MATLAB into my MEX file: struct('speed',{100.3},'nr',{55.4},'on',{54}), but the last value which is defined in my MEX file as unsigned char reads out as zero before calling my C function? The two double values works like intended.
struct post_TAG
{
double speed;
double nr;
unsigned char on;
};
const char *keys[] = { "speed", "nr", "on" };
void testmex(post_TAG *post)
{
...
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
post_TAG post;
int numFields, i;
const char *fnames[3];
mxArray *tmp;
double *a,*b;
unsigned char *c;
numFields=mxGetNumberOfFields(prhs[0]);
for(i=0;i<numFields;i++)
fnames[i] = mxGetFieldNameByNumber(prhs[0],i);
tmp = mxGetField(prhs[0],0,fnames[0]);
a=(double*)mxGetData(tmp);
tmp = mxGetField(prhs[0],0,fnames[1]);
b=(double*)mxGetData(tmp);
tmp = mxGetField(prhs[0],0,fnames[2]);
c=(unsigned char*)mxGetData(tmp);
mexPrintf("POST0, speed=%f, nr=%f, on=%u\n",*a,*b,*c);
post.speed = *a;
post.nr = *b;
post.on = *c;
testmex(&post);
}
In a struct defined as struct('speed',{100.3},'nr',{55.4},'on',{54}), the field on is a double. Pass as a uint8 from MATLAB:
struct('speed',{100.3},'nr',{55.4},...
'on',{uint8(54)}),
Any numeric value without a specified type in MATLAB is a double.
Also note that for reading a scalar value, the problem is simplified somewhat by mxGetScalar. It will return one double value for any underlying data type.
unsigned char s = (unsigned char) mxGetScalar(...); // cast a double to unsigned char

Array of int at the output of a mex file

I am trying to create a mex function whose entry is an integer and whose output is an array of integer.
So the function looks like: int *myFunction(unsigned int N).
In the mexFunction, I declare a variable *variab of type int and then
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
siz= 2*ceil(log(1.0*N)/log(2.0)-0.5)+1;
plhs[0] = mxCreateDoubleMatrix(1,siz, mxREAL);
vari = (int*) mxGetPr(plhs[0]); */
/* Call the subroutine. */
vari = myFunction(N);
mexPrintf("The first value is %d\n", vari[0]);
The thing is the first value is the correct one (and the other ones were checked and were correct as well) but when I call the routine mxFunction(16), I get only 0's as output.
I guess it is because my output is an array of int but I don't know how to solve the problem. Any hint?
Cheers.
Matlab deals with doubles by default. You can easily cast them in your mex function like the following example based on your code snippet. I have made a myFunction that performs a demo algorithm. Rather than return a data type, I make it a void function and pass it a pointer to the output so that it can populate it . . .
/*************************************************************************/
/* Header(s) */
/*************************************************************************/
#include "mex.h"
#include "math.h"
/*************************************************************************/
/*the fabled myFunction */
/*************************************************************************/
void myFunction(unsigned int N, unsigned int siz, double* output)
{
int sign = 1;
for(int ii=0; ii<siz; ++ii)
{
output[ii] = (double)(ii * sign + N);
sign *= -1;
}
}
/*************************************************************************/
/* Gateway function and error checking */
/*************************************************************************/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* variable declarations */
unsigned int siz;
double N;
/* check the number of input and output parameters */
if(nrhs!=1)
mexErrMsgTxt("One input arg expected");
if(nlhs > 1)
mexErrMsgTxt("Too many outputs");
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
siz= 2*ceil(log(1.0*N)/log(2.0)-0.5)+1;
plhs[0] = mxCreateDoubleMatrix(1,siz, mxREAL);
myFunction(N, siz, mxGetPr( plhs[0]) );
}

Error in lex program?

I was making this very simple lex program (just an introductory program). But on compiling lex.yy.c, I am getting this error as:
inToPostfix.l:26: error: ‘struct stackoperand’ has no member named ‘top’
inToPostfix.l:32: error: ‘struct stackoperator’ has no member named ‘top’....
I could not make any reason for this error as I already have defined top in the specified structure.
Can you see any reason for it?
Code is posted at http://pastebin.com/d5f059c1d
Here is a diff against your original. It fixes all the problems when compiling:
--- orig.l 2009-11-09 14:55:47.414002041 -0500
+++ kk.l 2009-11-09 14:54:53.386385539 -0500
## -1,14 +1,15 ##
%{
#include<stdio.h>
%}
+ int precedence(char a,char b);
struct stackoperator{
char stack[10];
- int top =-1;
+ int top;
};
struct stackoperand{
int stack[10][2];
- int top =-1;
+ int top;
};
struct stackoperator operator;
struct stackoperand operand;
## -29,6 +30,7 ##
}
[ \t] ;
[\n] {
+ char ch;
while(operator.top!=-1)
{
ch=pop();
Move line 3 to line 16.
You also need to remove the initializers from the structure declarations - at least for C (but the C++ compiler didn't think much of it either).
struct stackoperator
{
char stack[10];
int top =-1;
};
To:
struct stackoperator
{
char stack[10];
int top;
};
In the actions, you also need to declare 'ch'.
You also need to declare your functions - I made them static. This compiles (assuming you have a C99 compiler - the designated initializers won't work with C89 compilers):
%{
#include<stdio.h>
struct stackoperator
{
char stack[10];
int top;
};
struct stackoperand
{
int stack[10][2];
int top;
};
struct stackoperator operator = { .top = -1 };
struct stackoperand operand = { .top = -1 };
int num=0;
static void push(int num,int flag);
static int pop(void);
static int precedence(char a,char b);
%}
%%
[0-9] {num=num*10+(*yytext-'0');push(num,1);}
[-+*/] {
if(precedence(operator.top,*yytext)) {
char ch=pop();
push(ch,0);
operand.stack[operand.top][1]=1;
}
push(*yytext,0);
}
[ \t] ;
[\n] {
char ch;
while(operator.top!=-1)
{
ch=pop();
push(ch,0);
}
int i=0;
while(i<=operand.top)
{
if(operand.stack[operand.top][1]==1)
printf(" %c ",operand.stack[operand.top][0]);
else
printf(" %d ",operand.stack[operand.top][0]);
}
}
%%
static void push(int num,int flag)
{
if(flag)
{ operand.top++;
operand.stack[operand.top][0]=num;
operand.stack[operand.top][1]=0;
}
else
operator.stack[++operator.top]=num;
}
static int pop(void)
{
return operator.stack[operator.top--];
}
static int precedence(char a,char b)
{
if(operator.top==-1)
return 0;
if((a=='*'||a=='/') && (b=='+'||b=='-'))
return 1;
else
return 0;
}