Structs allgemein, dynamische Erstellung usw. [Titel geändert]
-
Bitte weiter unten schauen, falls der Thread noch aktuell ist, ich nutze ihn weiterhin für Fragen zum Thema Struct.
Hallo,
Ich programmiere noch nicht lange in C(wie man am Anmeldungsdatum sieht hatte ich es aber schonmal vor :P), habe aber schon Kenntnisse aus Basic bzw. BlitzMax.
Das Problem dass sich mir nun ergeben hat, ist folgendes:
Ich definiere in einem Header ein Struct mit 4 Variablen, "typedeffe" dieses und möchte schon eine Instanz im Header erstellen, was ja mit dem Instanzenname nach der geschweiften Klammer zu und vor dem Semikolon möglich sein sollte.
Nun mosert mir aber die IDE(Netbeans) in einer .c Datei herum, wenn ich auf eine Variable der im Header festgelegten Instanz zugreifen möchte.
Die Meldung von der IDE ist dann "unexpected token", das kommt sowohl beim Instanzenname, als auch beim Zugriffspunkt und der Variablen.
Die Headerdatei ist in der .c Datei natürlich inkludiert.Hier der Header:
#ifndef DSE_INPUT_INCLUDED #define DSE_INPUT_INCLUDED #ifdef BUILD_DLL #define DSE_API __declspec( dllexport ) #elif BUILD_LIB #define DSE_API #else #ifdef __cplusplus #define DSE_API extern "C" __declspec( dllimport ) #else #define DSE_API __declspec( dllimport ) #endif #endif #include "input_keycodes.h" DSE_API void keyDown( unsigned char key, int x, int y ); DSE_API void keyUp( unsigned char key, int x, int y ); struct _dseInput { unsigned char keyState[ DSE_KEY_AMOUNT ]; unsigned char keyReference[ DSE_KEY_AMOUNT ]; unsigned char keyTimer[ DSE_KEY_AMOUNT ]; }Input; typedef struct _dseInput dseInput; void processTimers( void ); #endif /* DSE_INPUT_INCLUDED */
Und hier der Source:
#include "../include/input.h" /* Die folgende Zeile funktioniert z.B. schon nicht, also die IDE mosert * entsprechend herum... */ Input.keyState[ 0 ] = 5;
Um die Fehlerquelle zu erschließen, hatte ich ein neues Projekt erstellt und dort genauso ein Struct definiert und dort lief so alles glatt, allerdings ist dies keine DLL, sondern eine normale Konsolenanwendung.
Zum Kompilieren und Linken nutze ich MinGW.Ahja, das Inputzeugs soll eigentlich mal für eine simple OpenGL Engine dienen, die ich lediglich zum lernen von C und OpenGL bzw. 3D-Programmierung schreiben will. Ich benutze dafür FreeGLUT.
Ich bin dankbar für jede Hilfe, auch bin ich dankbar für Hinweise auf eventuelle andere Fehler.
MfG DaysShadow
-
also ich verwende structs immer so, was nicht heißt das deine variante falsch ist...
typedef struct Input_s { unsigned char keyState[ DSE_KEY_AMOUNT ]; unsigned char keyReference[ DSE_KEY_AMOUNT ]; unsigned char keyTimer[ DSE_KEY_AMOUNT ]; }Input_t;
und dann wär sowas möglich
Input_t Input = { .keyState={0,1,2,3,4} ,.keyReference={0,1,2,3,4} };
falls du deine variante verwenden willst also "Input.keyState[0] = 111;" mußt du das in eine function packen also in die main(){...} oder eine andere die du dann z.b. ...initStruct(...){Input.keyState[0] = 111;} ...main(...){initStruct();} so initialisierst
btw. wo kommen eigentlich die x und y coors her die du den functionen keyUp und keyDown übergibts? würd die da eher raus machen
lg lolo
-
Ah, so einfach kann es sein.
Jetzt wo ich das lese, habe ich bei dem anderen Projekt, was scheinbar funktionierte, probiert die Instanz zu nutzen - geht da aber genauso wenig.
Also außerhalb von main sind diese Instanzen nicht direkt ansprechbar, sofern ich das jetzt richtig verstanden habe.Und die Parameter int x und int y gehören da hin, weil die Funktionen für die Callbacks von glut bzw. freeglut sind und die sind nunmal so definiert
Aber vielen Dank für die Hilfe.
MfG DaysShadow
-
außerhalb einer funktion kannst die dinger nur initialisieren.
wirf doch da mal nen blick reinlg lolo
-
So, ich hätte da nochmal eine Frage:
Header:
struct _MyStruct { int a; float b; double c; unsigned char arr[ 20 ]; }Test; typedef struct _MyStruct MyStruct; MyStruct* pTest; void initMyStruct( MyStruct* myStruct, int a, float b, double c );
Source:
#include <stdlib.h> #include <stdio.h> #include "../include/header.h" void initMyStruct( MyStruct* myStruct, int a, float b, double c ) { myStruct = (MyStruct*) calloc( 1, sizeof( MyStruct ) ); if( myStruct == NULL ) printf( "%s", "myStruct initialization failed" ); myStruct->a = a; myStruct->b = b; myStruct->c = c; myStruct->arr[ 0 ] = 5; }
Und zwar möchte ich pTest in main( ) mit der initMyStruct(...) Funktion initialisieren, allerdings erhalte ich nicht die Fehlermeldung, dass myStruct == NULL ist sondern das Programm wird von Windows beendet.
Wo ist der Fehler? Ich bin mal wieder ratlos...MfG DaysShadow
-
Mal reinwerfen..
http://c-faq.com/malloc/mallocnocast.html
-
Hm, ok, wo genau ist jetzt das Problem, ich habe gerade noch gelesen dass man malloc in C nicht castet in C++ aber schon, da ich momentan in C Programmiere also demnach kein cast.
Angewendet -> Mein Programm schmiert immer noch ab, ist das Problem jetzt der Pointer myStruct?Vllt ein klitzekleines bisschen erklärt für einen blöden Anfänger?
MfG DaysShadow
-
DaysShadow schrieb:
void initMyStruct( MyStruct* myStruct, int a, float b, double c ) { myStruct = (MyStruct*) calloc( 1, sizeof( MyStruct ) ); if( myStruct == NULL ) printf( "%s", "myStruct initialization failed" ); myStruct->a = a; myStruct->b = b; myStruct->c = c; myStruct->arr[ 0 ] = 5; }
Diesen Code kannst du genauso gut ersetzen durch:
void initMyStruct( MyStruct* myStruct, int a, float b, double c ) { calloc( 1, sizeof 8MyStruct ) ); }
Erklärung: C kennt ausschließlich call by value. Das bedeutet die Parameter Werte sind immer Kopien.
Du übergibst der Funktion also einen Zeiger. Diesen Zeiger ersetzt du aber sofort durch den Rückgabewert von calloc. Der Übergebene Wert ist schonmal futsch. Vermutlich willst du, dass der Wert von calloc auch außerhalb der Funktion noch verfügbar ist. Dafür eignen sich Doppelzeiger.
void init(MyStruct **s) /* Doppelzeiger */ { *s = calloc(1, sizeof(MyStruct)); /* s erst dereferenzieren! */ } int main(void) { MyStruct *s; init(&s); /* Adresse der Zeigervariable übergeben! */ }
Eleganter ist es allerdings den neuen Zeiger als Rückgabewert zu haben.
MyStruct* init(void) { MyStruct *new = calloc(1, sizeof(MyStruct)); /* Mach initialisierungen hier */ return new; } int main(void) { MyStruct *s = init(); }
-
Das hilft mir schonmal sehr, vielen Dank!
MfG DaysShadow
-
[EDIT] Hat sich erledigt, man sollte natürlich auch Variablen exportieren wenn man diese braucht...[/EDIT]
So weiter gehts mit den Fragen
Eigentlich hatte ich ja gehofft keine mehr stellen zu müssen aber naja...Ich habe einen Pointer auf ein Struct in einem Header definiert und dem möchte ich in einer Funktion mit der Createfunktion Inhalt geben.
Das scheint aber nicht zu funktionieren da sich das Programm, mal wieder, verabschiedet.
Gebe ich dem Pointer in main( ) den Inhalt direkt mit der Createfunktion oder auch InitSampleStruct geht es allerdings...Wie auch schon davor, soll das alles in eine DLL, aber ich denke da liegt der Fehler nicht.
Ich hoffe ich nerve nicht
Danke und MfG
DaysShadow/*Header*/ #ifndef _FUNCTIONS_H #define _FUNCTIONS_H //Exportzeugs herrausgeschnitten #include <stdio.h> #include <stdlib.h> typedef struct { unsigned char sample; unsigned char* samplePointer; }SampleStruct; EXPORT SampleStruct* CreateSampleStruct( unsigned char smpl, unsigned char pSize); EXPORT void InitSampleStruct( SampleStruct** smplStrct, unsigned char smpl, unsigned char pSize); SampleStruct* smplStct; EXPORT void InitSomething( void ); /* Ruft CreateSampleStruct für smplStct auf */ #endif /* _FUNCTIONS_H */
/*Source*/ #include "../include/functions.h" EXPORT SampleStruct* CreateSampleStruct( unsigned char smpl, unsigned char pSize ) { SampleStruct* new = malloc( sizeof( SampleStruct ) ); new->sample = smpl; new->samplePointer = calloc( pSize, sizeof( unsigned char ) ); new->samplePointer[ 0 ] = 5; return new; } EXPORT void InitSampleStruct( SampleStruct** smplStrct, unsigned char smpl, unsigned char pSize) { *smplStrct = malloc( sizeof( SampleStruct ) ); (*smplStrct)->sample = smpl; (*smplStrct)->samplePointer = calloc( pSize, sizeof( unsigned char ) ); (*smplStrct)->samplePointer[ 0 ] = 5; } EXPORT void InitSomething( void ) { smplStct = CreateSampleStruct( 5, 5 ); /* Hier liegt wohl der Fehler */ }