Compiling with .h headers and .c source files.

I have a problem. The Arduino IDE outputs this from the console. I'm trying to compile the .h and .c files with the .ino files. I have put the .c and .h files next to the .ino file. It looks like the .h files can be resolved because there is no mention of problems with the structs in the same .h files.

Eind_Project.cpp.o: In function `setup':
C:\Program Files (x86)\Arduino/Eind_Project.ino:11: undefined reference to `container_create(EventContainer*)'
C:\Program Files (x86)\Arduino/Eind_Project.ino:14: undefined reference to `container_create_event(EventContainer*, char*, unsigned char)'
C:\Program Files (x86)\Arduino/Eind_Project.ino:17: undefined reference to `container_add_listener(EventContainer*, char*, void (*)(void*))'
Eind_Project.cpp.o: In function `loop':
C:\Program Files (x86)\Arduino/Eind_Project.ino:33: undefined reference to `container_get(EventContainer*, char*)'
C:\Program Files (x86)\Arduino/Eind_Project.ino:33: undefined reference to `event_send(Event*, void*)'
collect2.exe: error: ld returned 1 exit status
Error compiling.

Main.ino file:

#include "EventArgs.h"
#include "Event.h"
#include "EventContainer.h"

EventContainer* events;
uint8_t ledStatus = 0;

void setup()
{
	// setup events
	container_create(events);

	// Create led event
	container_create_event(events, "LedEvent", 0);

	// Setup event handler
	container_add_listener(events, "LedEvent", handleLed);

	//init onboard led
	pinMode(13, OUTPUT);
}

void loop()
{
	// Invert ledStatus 
	ledStatus = ledStatus == 1 ? 0 : 1;

	// Create event arguments
	LedEventArgs* args;
	args->status = ledStatus;

	// Send event
	event_send(container_get(events, "LedEvent"), (void*)args);

	// Delay thread for 500 msec
	delay(500);
}

void handleLed(void *on) {
	// Write received status to onboard led
	digitalWrite(13, ((LedEventArgs*)on)->status);
}

EventArgs.h:

// EventArgs.h

#ifndef _EVENTARGS_h
#define _EVENTARGS_h

typedef struct {
	uint8_t status;
} LedEventArgs;

#endif

EventContainer.h

// EventContainer.h

#ifndef _EVENTCONTAINER_h
#define _EVENTCONTAINER_h

#if defined(ARDUINO) && ARDUINO >= 100
	#include "arduino.h"
#else
	#include "WProgram.h"
#endif

#include "Event.h"

#define INITIAL_CONTAINER_SIZE 4

typedef struct
{
	Event **events;

	short count;
	short capacity;
} EventContainer;

void container_create(EventContainer *container);
void container_free(EventContainer *container);

Event *container_get(EventContainer *container, char *eventName);

Event* container_create_event(EventContainer *container, char *eventName, byte safe);
void container_add_listener(EventContainer *container, char *eventName, void(*callback)(void *));

#endif

Event.h

// Event.h

#ifndef _EVENT_h
#define _EVENT_h

#define INITIAL_EVENT_CAP 2

typedef struct
{
	char* eventName;
	void **callbacks;

	short size;
	short capacity;
} Event;

void event_create(Event *event_s, char *eventName);

void event_send(Event *event_s, void *context);
void event_add(Event *event_s, void(*callback)(void *));

#endif

line 11 is wrong. Oh or it may be before that.

Mark

I added all the code files to my first question.

I haven't kept up with the changes but there used to be an IDE hoop to jump through getting it to recognize classes. OTOH I have put .h and .cpp files in the IDE libraries folder and they work but I have to edit those outside the IDE or the updates go to the wrong folder.

Perhaps this is what happens when you use Java in a C compiler.

Ok when I put the files in the libraries folder, it says it can't find any file or folder with that name. When I put the files in a folder in libraries like: libraries/Evented/[files] then the same errors occur as before.

Which is interesting because it doesn't say anything about the structs, it looks like it can find those without a problem. When I alter one of the typedef'ed structs it starts to add this about the wrong struct name:

Eind_Project.ino:3:1: error: 'TimerContainers' does not name a type

The actual type would be TimerContainer. So it looks like the function signatures are wrong?

After countless hours of Googling I found something. Because this is the first time I'm actually going into the slightly deeper parts of C I didn't know that C++ function names are mangled names. That means they are not just function_call() but exist out of the class name, function name and arguments. Thus I had to wrap the includes so that the compiler knows to use the C way of calling a function.

Add this arround the includes that reference C header files.

extern "C" {
    #include "EventArgs.h"
    #include "Event.h"
    #include "EventContainer.h"
}

Add this arround the includes that reference C header files.

Or rename the .c files to .cpp.