I am developing a OS X Swift app for parsing cvs files. It runs successfully in Objective-C. Then I changed to Swift and for performance improvements I developed the parse/import engine in C. It is 5 times faster as in Swift or Objective-C - nice. But I have trouble to exchange the data between C and Swift - especially with Struct:
BridgingHeader:
#include "ToolBoxC.h"
ToolBoxC.h:
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);
typedef struct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
} FileStruct;
typedef struct {
FileStruct fileContent[10000];
} FilesStruct;
struct FilesStruct filesContent;
ToolBoxC.c:
struct FileStruct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
};
struct FilesStruct {
struct FileStruct fileContent[10000];
};
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {
// some stuff
struct FileStruct fileContent;
fileContent.headerArray = headerArray;
fileContent.numberHeaderRows = numberHeaderRows;
fileContent.dateArray = dateArray;
fileContent.numberDateRows = numberDateRows;
fileContent.valueArray = valueArray;
fileContent.stringArray = stringArray;
fileContent.numberValueRows = numberValueRows;
fileContent.numberValueColums = numberValueColumns;
filesContent.fileContent[numberFiles] = fileContent;
return;
}
All the parsed data are stored in struct FilesStruct filesContent. The parsing is started by calling the function loadFile() with parameters from Swift. That works fine. Also the parsing is OK. But how can I access to the data in struct FilesStruct filesContent from Swift?
Thanks, Matthias.
Try this:
ToolBoxC.h
#include <stdbool.h>
struct FileStruct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
};
extern struct FileStruct **loadedFiles;
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);
ToolBoxC.c
#include <stdlib.h>
#include "ToolBoxC.h"
#define MaxFiles 10000
struct FileStruct **loadedFiles;
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {
static int nextIndex = 0;
if (loadedFiles == 0)
loadedFiles = malloc(MaxFiles * sizeof(*loadedFiles));
struct FileStruct *file = malloc(sizeof(struct FileStruct));
file->numberDateRows = xRow;
loadedFiles[nextIndex++] = file;
}
Swift Test Method
func loadFilesTest() -> Void {
for var i:Int32 = 0; i < 10; ++i {
loadFile("", "", "", 0, 0, 0, i, 0, true)
}
for var j = 0; j < 10; ++j {
let pointer = UnsafePointer<FileStruct>(loadedFiles[j])
print("Number of date rows = \(pointer.memory.numberDateRows)")
}
}
Related
I have a struct defined like this:
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
I have another struct called Complex in which I want a field to store an array of only Set struct IDs.
typedef struct {
char idComplesso[20];
content[10];
int dimLogica;
} complex;
So, I want the content array (of max size 10) to be able to store only the string id from a max of 10 Set.
How could I do this in C?
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
typedef struct {
char idComplesso[20];
int dimLogica;
size_t nsets;
char *content[];
} complex;
complex *assign(Set *s, size_t nsets)
{
complex *cml = malloc(sizeof(*cml) + nsets * sizeof(cml -> content[0]));
/* allocation check */
cml -> nsets = nsets;
for(size_t i = 0; i < nsets; i++)
{
cml -> content[i] = s[i].id;
}
return cml;
}
You'll have to make the content array be an array of char* and when you create the structure only accept id from a Set struct.
Something like this:
complex* createComplex(Set* sets) {
complex* comp = (complex*)malloc(sizeof(complex));
for (int i=0; i<10; i++) {
comp->content[i] = sets[i].id;
}
return comp;
}
And don't let any other function create the comp struct
I have difficulty applying the pass by reference and pass by value separation in structs.How can I swap the elements of the fixed size struct array as below.
struct try{
int num;
char name[10];
};
int main(){
struct try book[3];
void swapper(/********/);// <-what should be the argument of this function
}
void swapper(/********/){//swap second and third element of struct array
/*how the swap may be done?
temp=book[2];
book[2]=book[3];
temp=book[3];*/
}
There are a lot of ways to do what you're asking. One approach:
#include <stdio.h>
struct try {
int num;
char name[10];
};
void
swapper(struct try *a, int b, int c)
{
struct try tmp = a[b];
a[b] = a[c];
a[c] = tmp;
}
void
display(const struct try *t, size_t count)
{
while( count-- ){
printf("%d: %s\n", t->num, t->name);
t += 1;
}
}
int
main(void) {
struct try book[] = {
{ 1, "foo"},
{ 2, "bar"},
{ 3, "baz"}
};
display(book, sizeof book / sizeof *book);
swapper(book, 1, 2);
display(book, sizeof book / sizeof *book);
return 0;
}
I am trying to pass a string array and indexes from where to start end searching in the array, I am unable to solve it from the last two days. I am sending to the pthread_create a struct data thread_data, here i am able to send the int and long data, but not the string array, can someone help me, how to pass these.
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
char * str;
};
struct data thread_data[NUM_THREADS];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
char * str[3];
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
.....
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
...
char work[]={"First Line","Second line","Third line"};
...
while(fgets(arr[index],120, fp)!=NULL){
index=index+1;
thread_data[index].tid=index;
thread_data[index].str=work;
...
rc=pthread_create(&threads[index],NULL,searchString,(void *)&thread_data[index]);
...
}
pthread_exit(NULL);
}
To hold the multiple strings you need 2D array.
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
You need to use pointer to pointer in struct data to hold the above array.
struct data{
.....
const char **str;
size_t lenOfStr;
};
And pass the length of array explicitly to thread function from main function.
Your sample code may look like below.
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
const char **str;
size_t lenOfStr;
};
struct data thread_data[3];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
const char **str = NULL;
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
int i = 0;
for (i = 0;i<t_data->lenOfStr;i++)
printf("%s\n", str[i]);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
int index = 0;
pthread_t threadid=0;
thread_data[index].tid=index;
thread_data[index].str=work;
thread_data[index].lenOfStr = sizeof(work)/sizeof(*work); // Calculate the size of work here
int rc=pthread_create(&threadid,NULL,searchString,&thread_data[index]);
pthread_exit(NULL);
}
I am trying to allocate space inside a struct. This struct contains information of a network packet.
The structure:
struct STRUCT_SVC_ROOM_CREATE
{
PacketHeader Header;
unsigned char TitleLength;
char* RoomTitle = new char[TitleLength];
short SuddenFactor;
short GameModeFactor;
unsigned char Password[4];
int MaxMen;
};
See this two lines of code
unsigned char TitleLength;
char* RoomTitle = new char[TitleLength];
1st -> The length of text (1 byte)
2nd -> The text itself (TitleLength bytes)
And this is how I create the struct based into another.
STRUCT_SVC_ROOM_CREATE* RoomCreate = (STRUCT_SVC_ROOM_CREATE*)pHeader;
pHeader is another struct, this contains all the information. Then I put into another struct to get the right data location.
But it doesnt work. So the question: How to allocate space correctly and build the struct char* with the size specified in TitleLength?
You shouldnt initialise the object inside the struct definition.
struct STRUCT_SVC_ROOM_CREATE
{
PacketHeader Header;
unsigned char TitleLength;
char* RoomTitle;
short SuddenFactor;
short GameModeFactor;
unsigned char Password[4];
int MaxMen;
};
void someFunction()
{
STRUCT_SVC_ROOM_CREATE* foo = new STRUCT_SVC_ROOM_CREATE;
foo->TitleLength = 10;
foo->RoomTitle = new char[foo->TitleLength];
}
Here is the requested class implementation (not tested):
class SVC_ROOM_CREATE{
private:
PacketHeader Header;
char* RoomTitle;
short SuddenFactor;
short GameModeFactor;
unsigned char Password[4];
int MaxMen;
public:
SVC_ROOM_CREATE(PacketHeader packet_header, int length, short sud_factor, short gm_factor, unsigned char pwd[], int max)
{
Header = packet_header;
RoomTitle = new char[length];
SuddenFactor = sud_factor;
GameModeFactor = gm_factor;
memcpy( Password, pwd, sizeof(Password));
MaxMen = max;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
PacketHeader Header;
unsigned char bar[4] = "pas";
int TitleLength = 10;
int SuddenFactor = 1;
int GameModeFactor = 2;
int MaxMen = 15;
SVC_ROOM_CREATE* foo = new SVC_ROOM_CREATE(Header, TitleLength, SuddenFactor, GameModeFactor, bar, MaxMen);
return 0;
}
I'm fairly new to C programming (did a little bit of lazarus and java before, but nothing mayor) and I tried to program a little text-rpg to learn the basics.
Now I'm getting a strange error while compiling since I tried to make part of the program a header. At the same time I stopped writing struct everywhere and used typedef, so the error might also originate from there.
Here's my code:
advancedgame.c:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "advancedgameglobals.h"
int main(int argc, char *argv[])
{
initiateglobals();
destroygameglobals();
return 0;
}
advancedgameglobals.c:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "advancedgameglobals.h"
PLAYER *player_create(char *name, int con, int str, int agi, int wis){
PLAYER *who = malloc(sizeof(PLAYER));
assert(who != NULL);
who->name = strdup(name);
who->con = con;
who->str = str;
who->agi = agi;
who->wis = wis;
int def = con / 5;
int maxhp = con * 10;
int hp = maxhp;
int maxmp = wis * 5;
int mp = maxmp;
who->def = def;
who->maxhp = maxhp;
who->hp = hp;
who->maxmp = maxmp;
who->mp = mp;
who->exp = 0;
who->level = 1;
}
char * determine_item_type(int type){
char *typename;
if(type == 1){
typename = "longsword";}
else if(type == 2){
typename = "wooden shield";}
else{
typename = "empty slot";}
return typename;
}
INVENTORY *inventory_create(char *name){
INVENTORY *who = malloc(sizeof(INVENTORY));
assert(who != NULL);
who->name = strdup(name);
int slot0 = 0;
int slot1 = 0;
int slot2 = 0;
int slot3 = 0;
int slot4 = 0;
int slot5 = 0;
int slot6 = 0;
int slot7 = 0;
int slot8 = 0;
int slot9 = 0;
who->slot0 = slot0;
who->slot0name = determine_item_type(slot0);
who->slot1 = slot1;
who->slot1name = determine_item_type(slot1);
who->slot2 = slot2;
who->slot2name = determine_item_type(slot2);
who->slot3 = slot3;
who->slot3name = determine_item_type(slot3);
who->slot4 = slot4;
who->slot4name = determine_item_type(slot4);
who->slot5 = slot5;
who->slot5name = determine_item_type(slot5);
who->slot6 = slot6;
who->slot6name = determine_item_type(slot6);
who->slot7 = slot7;
who->slot7name = determine_item_type(slot7);
who->slot8 = slot8;
who->slot8name = determine_item_type(slot8);
who->slot9 = slot9;
char *test = determine_item_type(slot9);
who->slot9name = test;//determine_item_type(slot9);
}
char * determine_town_type(int type){
char *typename;
if(type == 1){
typename = "shop";}
else if(type == 2){
typename = "Colloseum";}
else{
typename = "empty shack";}
return typename;
}
TOWN *town_create(char *name, int slot0, int slot1, int slot2, int slot3){
TOWN *who = malloc(sizeof(TOWN));
assert(who != NULL);
who->name = strdup(name);
who->slot0 = slot0;
who->slot0name = determine_town_type(slot0);
who->slot1 = slot1;
who->slot1name = determine_town_type(slot1);
who->slot2 = slot2;
who->slot2name = determine_town_type(slot2);
who->slot3 = slot3;
char *test = determine_town_type(slot3);
who->slot3name = test;//determine_town_type(slot3);
}
ENEMY *enemy_create(char *name, int con, int str, int agi, int wis){
ENEMY *who = malloc(sizeof(ENEMY));
assert(who != NULL);
who->name = strdup(name);
who->con = con;
who->str = str;
who->agi = agi;
who->wis = wis;
int def = con / 5;
int maxhp = con * 10;
int hp = maxhp;
int maxmp = wis * 5;
int mp = maxmp;
who->def = def;
who->maxhp = maxhp;
who->hp = hp;
who->maxmp = maxmp;
who->mp = mp;
int exp = con+str+agi+wis;
who->exp = exp;
who->level = exp / 50;
}
void player_destroy(PLAYER *who){
assert(who != NULL);
free(who->name);
free(who);
}
void enemy_destroy(ENEMY *who){
assert(who != NULL);
free(who->name);
free(who);
}
void inventory_destroy(INVENTORY *who){
assert(who != NULL);
free(who->name);
free(who);
}
void town_destroy(TOWN *who){
assert(who != NULL);
free(who->name);
free(who);
}
int initiateglobals(void)
{
PLAYER *PLAYER = player_create(
"Player", 10, 10, 10, 10);
INVENTORY *INVENTORY = inventory_create(
"Inventory");
TOWN *TOWN = town_create(
"Antaria", 2, 1, 0, 0);
return 0;
}
int destroygameglobals(void)
{
player_destroy(PLAYER);
inventory_destroy(INVENTORY);
town_destroy(TOWN);
}
advancedgameglobals.h:
#ifndef ADVANCEDGAMEGLOBALS_H
#define ADVANCEDGAMEGLOBALS_H
typedef struct player{
char *name;
int con;
int def;
int str;
int agi;
int wis;
int maxhp;
int hp;
int maxmp;
int mp;
int exp;
int level;
} PLAYER;
typedef struct enemy{
char *name;
int con;
int def;
int str;
int agi;
int wis;
int maxhp;
int hp;
int maxmp;
int mp;
int exp;
int level;
} ENEMY;
typedef struct inventory{
char *name;
int slot0;
char *slot0name;
int slot1;
char *slot1name;
int slot2;
char *slot2name;
int slot3;
char *slot3name;
int slot4;
char *slot4name;
int slot5;
char *slot5name;
int slot6;
char *slot6name;
int slot7;
char *slot7name;
int slot8;
char *slot8name;
int slot9;
char *slot9name;
} INVENTORY;
typedef struct town{
char *name;
int slot0;
char *slot0name;
int slot1;
char *slot1name;
int slot2;
char *slot2name;
int slot3;
char *slot3name;
} TOWN;
PLAYER *player_create(char *name, int con, int str, int agi, int wis);
char * determine_item_type(int type);
INVENTORY *inventory_create(char *name);
char * determine_town_type(int type);
TOWN *town_create(char *name, int slot0, int slot1, int slot2, int slot3);
ENEMY *enemy_create(char *name, int con, int str, int agi, int wis);
void player_destroy(PLAYER *who);
void enemy_destroy(ENEMY *who);
void inventory_destroy(INVENTORY *who);
void town_destroy(TOWN *who);
int initiateglobals(void);
int destroyglobals(void);
#endif
Now the error I'm getting tells me the following:
error: expected expression before 'PLAYER'
player_destroy(PLAYER);
error: expected expression before 'INVENTORY'
inventory_destroy(INVENTORY);
error: expected expression before 'TOWN'
town_destroy(TOWN);
I'm getting this error whenever I try to make a function using any of my structures. Most likely this is a very dumb error and I'm sorry about that, but I would appreciate any help you could give me.
Problems:
The function initiateglobals() initializes local variables, not global variables. Naming variables to the same name as types is also not good because it is confusing.
The function calls in destroygameglobals() is not good. You have to use names of variables instead of type names to pass as arguments.
To fix:
Declare global variables to be initialized in initiateglobals() and have the function initialize the global variables, not local variables. The names of variables should be differ from the type names to avoid confusion.
Use names of the declared global variables, not type names as arguments in function calls in destroygameglobals().
I think problem is with this function.
int destroygameglobals(void)
{
player_destroy(PLAYER);
inventory_destroy(INVENTORY);
town_destroy(TOWN);
}
Check function calls in this function. Instead of passing some variable as arguments, you are passing data type as arguments. Which is no acceptable.