Compiling problems with C.

Hi,

I have a problem with some code from me, which compiles and runs well with Ubuntu 13.04 (gcc),
but on Windows 7 (32Bit) not.

I'll get always errors, when I compile it with gcc from mingw.

 error: expected ';', ',' or ')' before 'struct'

The message is pointed to this code from the header.

EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_rtu(char *interface);
EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_tcp(char *ipadress, int port);
EsPeEs_modbus_device_t* EsPeEs_modbus_device(char *name, EsPeEs_modbus_interface_t *interface, uint8_t adress, uint8_t regsize);

...

EsPeEs_spi_interface_t* EsPeEs_spi_interface(char *name);
EsPeEs_spi_device_t* EsPeEs_spi_device(char *name, EsPeEs_spi_interface_t *interface, uint8_t adress);

...

EsPeEs_i2c_interface_t* EsPeEs_i2c_interface(char *name);
EsPeEs_i2c_device_t* EsPeEs_i2c_device(char *name, EsPeEs_i2c_interface_t *interface, uint8_t adress);

Here is the header (EsPeEs.h):

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * Copyright (C) 2013 EsPeEs <espees.plc@gmail.com>
 * libEsPeEs is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * libEsPeEs is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _ESPEES_H_
#define _ESPEES_H_

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#include "modbus.h"

struct EsPeEs_modbus_interface_t_struct {
    char *Name;
    char *SerialPort;
    char *IPAdress;
    int Port;
	int Connected;
	modbus_t *Modbus;
};

struct EsPeEs_modbus_device_t_struct {
	char *Name;
	uint8_t Adress;
	uint16_t *Registers;
	uint8_t Size;
	struct EsPeEs_modbus_interface_t_struct *ModbusInterface;
};

struct EsPeEs_spi_interface_t_struct {
	char *Name;
};

struct EsPeEs_spi_device_t_struct {
	char *Name;
	uint8_t Adress;
    struct EsPeEs_spi_interface_t_struct *SPIInterface;
};

struct EsPeEs_i2c_interface_t_struct {
	char *Name;
};

struct EsPeEs_i2c_device_t_struct {
	char *Name;
	uint8_t Adress;
    struct EsPeEs_i2c_interface_t_struct *I2CInterface;
};

struct EsPeEs_preferences_t_struct {
	int Baudrate;
	char Parity; // "none", "even" or "odd"
	int DataBit;  // 5, 6, 7, 8
	int StopBit;  // 0, 1
	int SPISpeed;
};

typedef struct EsPeEs_modbus_interface_t_struct EsPeEs_modbus_interface_t;
typedef struct EsPeEs_spi_interface_t_struct EsPeEs_spi_interface_t;
typedef struct EsPeEs_i2c_interface_t_struct EsPeEs_i2c_interface_t;
typedef struct EsPeEs_modbus_device_t_struct EsPeEs_modbus_device_t;
typedef struct EsPeEs_spi_device_t_struct EsPeEs_spi_device_t;
typedef struct EsPeEs_i2c_device_t_struct EsPeEs_i2c_device_t;
typedef struct EsPeEs_preferences_t_struct EsPeEs_preferences_t;

EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_rtu(char *interface);
EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_tcp(char *ipadress, int port);
EsPeEs_modbus_device_t* EsPeEs_modbus_device(char *name, EsPeEs_modbus_interface_t *interface, uint8_t adress, uint8_t regsize);
void EsPeEs_modbus_interface_free(EsPeEs_modbus_interface_t *interface);
void EsPeEs_modbus_device_free(EsPeEs_modbus_device_t *device);
int EsPeEs_modbus_read_registers(EsPeEs_modbus_device_t *device);
int EsPeEs_modbus_write_registers(EsPeEs_modbus_device_t *device);

EsPeEs_spi_interface_t* EsPeEs_spi_interface(char *name);
EsPeEs_spi_device_t* EsPeEs_spi_device(char *name, EsPeEs_spi_interface_t *interface, uint8_t adress);
void EsPeEs_spi_interface_free(EsPeEs_spi_interface_t *interface);
void EsPeEs_spi_device_free(EsPeEs_spi_device_t *device);
int EsPeEs_spi_transmit(EsPeEs_spi_device_t *device, char *data);

EsPeEs_i2c_interface_t* EsPeEs_i2c_interface(char *name);
EsPeEs_i2c_device_t* EsPeEs_i2c_device(char *name, EsPeEs_i2c_interface_t *interface, uint8_t adress);
void EsPeEs_i2c_interface_free(EsPeEs_i2c_interface_t *interface);
void EsPeEs_i2c_device_free(EsPeEs_i2c_device_t *device);
int EsPeEs_i2c_read(EsPeEs_i2c_device_t *device);
int EsPeEs_i2c_write(EsPeEs_i2c_device_t *device, int data);

void EsPeEs_start_cycle();
void EsPeEs_stop_cycle();
uint16_t EsPeEs_average_cycle_time();
uint16_t EsPeEs_last_cycle_time();


#define EsPeEs_bit_read(value, bit) (((value) >> (bit)) & 0x01)
#define EsPeEs_bit_set(value, bit) ((value) |= (1UL << (bit)))
#define EsPeEs_bit_clear(value, bit) ((value) &= ~(1UL << (bit)))
#define EsPeEs_bit_write(value, bit, bitvalue) (bitvalue ? EsPeEs_bit_set(value, bit) : EsPeEs_bit_clear(value, bit))

#endif

Hope you can help, i am trying to solve this since 2 days.

Ah, I forgot the c-file.

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * Copyright (C) 2013 EsPeEs <espees.plc@gmail.com>
 * libEsPeEs is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * libEsPeEs is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "EsPeEs.h"

static bool __EsPeEs_PreferencesCreated__;
static EsPeEs_preferences_t *__EsPeEs_Preferences__ = NULL;

static void EsPeEs_create_preferences()
{
	if(!__EsPeEs_PreferencesCreated__)
	{
		__EsPeEs_Preferences__ = (EsPeEs_preferences_t*) malloc(sizeof(EsPeEs_preferences_t));
		__EsPeEs_Preferences__->Baudrate = 115200;
		__EsPeEs_Preferences__->Parity = 'N';
		__EsPeEs_Preferences__->DataBit = 8;
		__EsPeEs_Preferences__->StopBit = 1;
		__EsPeEs_Preferences__->SPISpeed = 500000;
		__EsPeEs_PreferencesCreated__ = true;
	};
}

static bool EsPeEs_modbus_device_ok(EsPeEs_modbus_device_t *device)
{
	if(device != NULL)
	{
		if((device->Name != NULL) && (device->Registers != NULL) && (device->ModbusInterface != NULL))
		{
			if((device->ModbusInterface->Name != NULL) && (device->ModbusInterface->Connected != -1))
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_rtu(char *interface)
{
	EsPeEs_create_preferences();
	if(interface != NULL)
	{
		EsPeEs_modbus_interface_t *new = (EsPeEs_modbus_interface_t*) malloc(sizeof(EsPeEs_modbus_interface_t));
		new->Name = interface;
        new->SerialPort = interface;
        new->IPAdress = "";
        new->Port = 0;
        new->Modbus = modbus_new_rtu(interface, 
                                      __EsPeEs_Preferences__->Baudrate,
                                      __EsPeEs_Preferences__->Parity,
                                      __EsPeEs_Preferences__->DataBit,
                                      __EsPeEs_Preferences__->StopBit);
		new->Connected = modbus_connect(new->Modbus);
		return new;
	}
	else
	{
		return NULL;
	}
}

EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_tcp(char *ipadress, int port)
{
	EsPeEs_create_preferences();
	if(ipadress != NULL)
	{
		EsPeEs_modbus_interface_t *new = (EsPeEs_modbus_interface_t*) malloc(sizeof(EsPeEs_modbus_interface_t));
		new->Name = ipadress;
        new->SerialPort = "";
        new->IPAdress = ipadress;
        new->Port = port;
        new->Modbus = modbus_new_tcp(ipadress, port);
		new->Connected = modbus_connect(new->Modbus);
		return new;
	}
	else
	{
		return NULL;
	}
}

EsPeEs_modbus_device_t* EsPeEs_modbus_device(char *name, EsPeEs_modbus_interface_t *interface, uint8_t adress, uint8_t regsize)
{
	if((name != NULL) && (interface != NULL))
	{
		EsPeEs_modbus_device_t *new = (EsPeEs_modbus_device_t*) malloc(sizeof(EsPeEs_modbus_device_t));
		new->Name = name;
		new->Adress = adress;
		new->Size = regsize;
		int s = sizeof(uint16_t) * regsize;
		new->Registers = (uint16_t*) malloc(s);
		new->ModbusInterface = interface;
		return new;
	}
	else
	{
		perror("Returned NULL device.\n");
		return NULL;
	}
}

void EsPeEs_modbus_interface_free(EsPeEs_modbus_interface_t *interface)
{
    if(interface != NULL)
    {
        if(interface->Connected != -1)
        {
            modbus_close(interface->Modbus);
        }
        modbus_free(interface->Modbus);
        free(interface);
    }
}

void EsPeEs_modbus_device_free(EsPeEs_modbus_device_t *device)
{
    if(device != NULL)
    {
        free(device);
    }
}

int EsPeEs_modbus_read_registers(EsPeEs_modbus_device_t *device)
{
	if(EsPeEs_modbus_device_ok(device))
	{
        modbus_set_slave(device->ModbusInterface->Modbus, device->Adress);
		int n = modbus_read_registers(device->ModbusInterface->Modbus, 0, device->Size, device->Registers);
		return n;
	}
	else
	{
		return -255;
	}
}

int EsPeEs_modbus_write_registers(EsPeEs_modbus_device_t *device)
{
	if(EsPeEs_modbus_device_ok(device))
	{
        modbus_set_slave(device->ModbusInterface->Modbus, device->Adress);
		int n = modbus_write_registers(device->ModbusInterface->Modbus, 0, device->Size, device->Registers);
		return n;
	}
	else
	{
		return -255;
	}
}

EsPeEs_spi_interface_t* EsPeEs_spi_interface(char *name)
{
    return NULL;
}

EsPeEs_spi_device_t* EsPeEs_spi_device(char *name, EsPeEs_spi_interface_t *interface, uint8_t adress)
{
    return NULL;
}

void EsPeEs_spi_interface_free(EsPeEs_spi_interface_t *interface)
{
}

void EsPeEs_spi_device_free(EsPeEs_spi_device_t *device)
{
}

int EsPeEs_spi_transmit(EsPeEs_spi_device_t *device, char *data)
{
    return -1;
}

EsPeEs_i2c_interface_t* EsPeEs_i2c_interface(char *name)
{
    return NULL;
}

EsPeEs_i2c_device_t* EsPeEs_i2c_device(char *name, EsPeEs_i2c_interface_t *interface, uint8_t adress)
{
    return NULL;
}

void EsPeEs_i2c_interface_free(EsPeEs_i2c_interface_t *interface)
{
}

void EsPeEs_i2c_device_free(EsPeEs_i2c_device_t *device)
{
}

int EsPeEs_i2c_read(EsPeEs_i2c_device_t *device)
{
    return -1;
}

int EsPeEs_i2c_write(EsPeEs_i2c_device_t *device, int data)
{
    return -1;
}

uint16_t __EsPeEs_LastCycleTime__;
long long __EsPeEs_AverageFullValue__;
long long __EsPeEs_AverageCounter__;
struct timeval __EsPeEs_StartCycleTime__, __EsPeEs_StopCycleTime__;

void EsPeEs_start_cycle()
{
    gettimeofday(&__EsPeEs_StartCycleTime__, NULL);
}

void EsPeEs_stop_cycle()
{
    gettimeofday(&__EsPeEs_StopCycleTime__, NULL);
    __EsPeEs_LastCycleTime__ = __EsPeEs_StopCycleTime__.tv_usec - __EsPeEs_StartCycleTime__.tv_usec;
    __EsPeEs_AverageFullValue__ = __EsPeEs_AverageFullValue__ + __EsPeEs_LastCycleTime__;
    __EsPeEs_AverageCounter__ = __EsPeEs_AverageCounter__ + 1;
}

uint16_t EsPeEs_average_cycle_time()
{
    return __EsPeEs_LastCycleTime__;
}
uint16_t EsPeEs_last_cycle_time()
{
    return (__EsPeEs_AverageFullValue__ / __EsPeEs_AverageCounter__);
}

(deleted)

That is the code for the PC, which connects to Arduino.

I'm developing a PLC, which uses decentral Modbus modules based on the Arduino.

You cut the file name and line number from that error message...

Yes,

I'm using 'Beremiz' as Software-PLC, which adds his own code. The line numbers would be wrong.

I think there is something wrong with the struct declarations or the functions are wrong declared.

Beremiz logouts this:

Zeige build in C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build
Generiere SoftPLC IEC-61131 ST/IL/SFC Code...
Kompilliere IEC Programm zu c-Code...
Extrahiere gefundene Variablen...
C Code erfolgreich generiert.
SPS :
   [CC]  plc_main.c -> plc_main.o
   [CC]  plc_debugger.c -> plc_debugger.o
   [CC]  config.c -> config.o
   [CC]  MainResource.c -> MainResource.o
0 :
   [CC]  CFile_0.c -> CFile_0.o
C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c:451:76: error: expected ';', ',' or ')' before 'struct'
C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c:453:102: error: expected ';', ',' or ')' before 'struct'
C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c:454:62: error: expected ';', ',' or ')' before 'struct'
C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c:460:76: error: expected ';', ',' or ')' before 'struct'
C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c:461:56: error: expected ';', ',' or ')' before 'struct'
"gcc.exe" -c "C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c" -o "C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.o"  "-IF:\EsPeEs\matiec\lib"
C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c:466:76: error: expected ';', ',' or ')' before 'struct'
Beendet mit Status 1(pid 1084)
C:\Users\clausismus\AppData\Roaming\.EsPeEs\Client\Unknown\build\CFile_0.c:467:56: error: expected ';', ',' or ')' before 'struct'
C Kompilierung von CFile_0.c fehlgeschlagen.
C Build fehlgeschlagen.

Well, there's your problem..... (we can't really help you with this).
Now you know where to look / ask questions.

Beremiz / EsPeEs is generating invalid C code. Check out the broken file (CFile_0.c) and see how it gets generated.
Then you'll know where to fix it.

I'm sorry, but you're misunderstanding me.
Before I wrote this thread, I checked the file 'CFile_0.c'.

In line 451 you'll find:

EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_rtu(char *interface);

In line 453 you'll find:

EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_tcp(char *ipadress, int port);

And so further.

So these lines make problems. As I said, I think, I wrote wrong declarations for the structs and the functions.

You can't work out compiler errors from one line of code. It could be the previous line, the next line, or however EsPeEs_modbus_interface_t or interface are defined, declared or whatever.

but on Windows 7 (32Bit) not.

So this is nothing to do with the Arduino?

As I said, I think, I wrote wrong declarations for the structs and the functions.

Which you haven't shown.

You'll have all information you need, the errors are on these lines.

EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_rtu(char *interface);
EsPeEs_modbus_interface_t* EsPeEs_modbus_interface_tcp(char *ipadress, int port);
EsPeEs_modbus_device_t* EsPeEs_modbus_device(char *name, EsPeEs_modbus_interface_t *interface, uint8_t adress, uint8_t regsize);

...

EsPeEs_spi_interface_t* EsPeEs_spi_interface(char *name);
EsPeEs_spi_device_t* EsPeEs_spi_device(char *name, EsPeEs_spi_interface_t *interface, uint8_t adress);

...

EsPeEs_i2c_interface_t* EsPeEs_i2c_interface(char *name);
EsPeEs_i2c_device_t* EsPeEs_i2c_device(char *name, EsPeEs_i2c_interface_t *interface, uint8_t adress);

You have to look in the header "EsPeEs.h".
These functions are declared there and the struct definitions too.
One of them must cause these errors.

#include "modbus.h"

Where is this file? If you expect people to help, you need to post ALL of the code. Where is your sketch that uses the code you have posted?

'modbus.h' belongs to third-party library called 'libmodbus'.
Here is a link to the header: libmodbus/modbus.h at master · stephane/libmodbus · GitHub

I suspect your main problem is some/all of the Arduino and 3rd party header files assume you are using C++ and not C. There are lots of valid C++ constructs that are not valid C. This means, that you should use a .cpp or .cc suffix for your file instead of .c to use the C++ language instead of C.

No, it should be C, I had a problem with Beremiz, because it takes only C code.
I wrote this library 2, first in C++, then arghhh in my head, and then I wrote it C.
SInce then, it did a well job in Ubuntu. Now I want to port it to Windows.

Could it be, that the 'gcc' from mingw can't compile the same C code, what
the 'gcc' from Ubuntu Linux compiles?

Unlikely. What version of gcc do they use? Are you invoking them with the exact same command line?

Judging by the download, this is nothing to do with the Arduino. It is simply a library for Windows/Linux called libmodbus.

It comes with a configure script, a makefile, and all the usual stuff.

The OP already says it compiles OK under Linux.

I have a problem with some code from me, which compiles and runs well with Ubuntu 13.04 (gcc),
but on Windows 7 (32Bit) not.

So it is nothing to do with the library code, nothing to do with the Arduino, and something to do with the environment under which you are compiling it, which you haven't said much about.

Mmm something wrong with $PATH or something like that?

Mark

Im using Windows 7 (32 Bit) with mingw (the bin directory is in the Environment-Variable PATH).
Do I have to include other directories from the mingw too?