Как да предам указател към структура във функция с помощта на C език?

нов съм в разработването с c. със сигурност ще дойде ден, когато ще имам нужда от вашата помощ. И предполагам, че този момент е сега :)

Какво се опитвам да направя: експериментирам с MySQL Api в C. За това исках да използвам структура, за да задържа моя SQLQuery и всичките му параметри, напр. потребителски данни за избор или вмъкване.

След това с няколко функции исках да добавя, премахвам и компилирам низа, за да го използвам в заявка.

За да използвам моята функция createSqlQuery, бих искал да предам препратка към моята SQLQuery структура в нея и да я променя във функцията. След като тази функция приключи, тя не трябва да излиза извън обхвата и все още може да се използва в основната функция.

Това е мястото, където съм заседнал в момента. Предполагам, че проблемът ми е доста прост, но след като го гледах и опитвах с часове, съм малко сляп, за да видя решението. С помощта на този въпрос: Предаване на указатели/препратки към структури във функции най-накрая се случи да има работещ код по начин, по който структурата все още може да се използва след края на функцията create.

Но по някаква причина не мога да компилирам кода си допълнително, защото не може да присвои нещо на моята структура.

Съобщение за грешка:

main.c:127:10: грешка: заявка за член „addParam“ в нещо, което не е структура или обединение

Това се случи след добавяне на втори * във функцията за създаване, за да получите указател към указател (вижте друг въпрос за stackoverflow).

Това е, което имам досега:

typedef struct sqlQuery sqlQuery;

struct sqlQuery{
    char *queryS;
    char **params; //array of array of chars to hold the params to replace %? in the query
    bool (*addParam)(sqlQuery*, char*);
    bool (*compile)(sqlQuery*);
};

int main(){
/* ...  */
    sqlQuery *testQuery = NULL;
    printf("%p\n", &testQuery);
    printf("%p\n", testQuery);
    createSqlQuery(&testQuery,"SELECT * FROM test WHERE name = '%?'");
    printf("%p\n", testQuery);
    if (testQuery != NULL) printf("working, testQuery still assigned");
    //testQuery->addParam(testQuery, "test");
    //freeSqlQuery(testQuery);

    exit(EXIT_SUCCESS);
}

bool createSqlQuery(sqlQuery **query, char *queryString){
    *query = (struct sqlQuery *) malloc(sizeof(struct sqlQuery));  //get heapspace for sqlQuery Struct
    printf("%p\n", *query);
    //query->addParam = __sqlQueryAddParam;      //link param function pointer
    //query->compile = __compileSqlQuery;        //link compile function pointer
    *query->queryS = queryString;               //save pointer to query String
    //^^^ this is where the error occurs

    return true;
}

Опитах също комбинации и вариации на:

(sqlQuery *)*query->queryS = queryString;

с ** или &...

Надявам се да разберете това, с което се боря, предполагам, че е просто, но наистина не мога да го разбера :)

Благодаря предварително!


person Daniel    schedule 04.06.2013    source източник
comment
Можете ли да направите бърза проверка за мен и да промените typedef struct sqlQuery sqlQuery; struct sqlQuery { ... }; само на typedef struct { ... } sqlQuery;   -  person slugonamission    schedule 04.06.2013
comment
О, да, тогава премахнете struct от всички употреби на struct sqlQuery.   -  person slugonamission    schedule 04.06.2013
comment
slugonamission: прав си. Първоначално ги нямах. по-късно ги добави, за да провери дали имат някаква разлика. unwind: ups :) копирах това от другия въпрос...   -  person Daniel    schedule 04.06.2013


Отговори (4)


Това се дължи на предимство на оператор, тъй като операторът за членски достъп -> има по-висок приоритет от операторът за дереференция *. промяна:

*query->queryS = queryString; 

to:

(*query)->queryS = queryString;

Други:

  • Не прехвърляйте върнатата стойност от malloc().
  • Кодът присвоява адреса на низов литерал, който е само за четене, на char*. Използвайте const char* или копирайте низа (използвайки malloc()/strcpy() или strdup(), ако вашата реализация го предоставя.
  • Не забравяйте да free() какво беше malloc()d.
person hmjd    schedule 04.06.2013

За повече простота опитайте

bool createSqlQuery(struct sqlQuery **ptrresultquery, char *queryString)
{
    struct sqlQuery *query = (struct sqlQuery *) malloc(sizeof(struct sqlQuery));  //get heapspace for sqlQuery Struct

     query->addParam = __sqlQueryAddParam;      //link param function pointer
     query->compile = __compileSqlQuery;        //link compile function pointer
     query->queryS = queryString;               //save pointer to query String

     // write the local pointer back via parameter ptr
     *ptrresultquery= query;

     return true;
}

В противен случай това, което искате да направите със синтаксиса си, е

    (*ptrresultquery)->queryS= queryString;
person Nicholaz    schedule 04.06.2013

с помощта на SoapUI тествам уеб услугите си и работят много добре. Когато се опитвам да го използвам с JDeveloper (използвайки същите HTTP заглавки на заявки) като SoapUI, той се проваля
person unwind    schedule 04.06.2013
comment
здравейте, започнах с това като моя първа идея :) sqlQuery* createSqlQuery(char *queryString){} промених го, за да мога лесно да направя if(!createSqlQuery(...)){/*обработване на грешки*/} - person Daniel; 04.06.2013

(*query)->queryS = queryString; ще свърши работата

И използвайте прототипи, ако извикате функция след main

bool createSqlQuery(sqlQuery **query, char *queryString);
person David Ranieri    schedule 04.06.2013
comment
благодаря ти за този намек. Коментирах ги в този пример! следващото нещо, което трябва да научите, е как да разделите тези неща на .h и .c и да използвате работещ Makefile :) - person Daniel; 04.06.2013