Hi
I was trying to create a sketch in my eclipse environment in Arduino 1.0 using the wire library.
The compilation failed. Investigation pointed out that my eclipse plugin compiles all files as C++ files where the Arduino IDE has the compiler select the C or C++mode.
As a consequence of this twi.c is compiled as C code and wire.cpp is compiled as C++ code in the Arduino IDE. In my plugin they are both compiled as C++.
wire.cpp includes twi.h as follows:
As a consequence twi.h is always compiled as C in the arduino IDE. However in the eclipse plugin it is compiled as C in wire.cpp an as C++ in twi.c.
I accept this can not be called a bug but I feel it would be nicer to change twi.h so that there is encapsulation of twi.h. (no need for extern "C" in wire.cpp). twi.h would look as follows:
/*
twi.h - TWI/I2C library for Wiring & Arduino
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef twi_h
#define twi_h
#include <inttypes.h>
//#define ATMEGA8
#ifndef TWI_FREQ
#define TWI_FREQ 100000L
#endif
#ifndef TWI_BUFFER_LENGTH
#define TWI_BUFFER_LENGTH 32
#endif
#define TWI_READY 0
#define TWI_MRX 1
#define TWI_MTX 2
#define TWI_SRX 3
#define TWI_STX 4
#ifdef __cplusplus
extern "C" {
#endif
void twi_init(void);
void twi_setAddress(uint8_t);
uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
uint8_t twi_transmit(const uint8_t*, uint8_t);
void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
void twi_attachSlaveTxEvent( void (*)(void) );
void twi_reply(uint8_t);
void twi_stop(void);
void twi_releaseBus(void);
#ifdef __cplusplus
}
#endif
#endif
As a consequence of this twi.c is compiled as C code and wire.cpp is compiled as C++ code in the Arduino IDE. In my plugin they are both compiled as C++.
I think that makes your plugin broken. Probably in easily fixable ways. I don't think there's a reason to change .c files in the arduino distribution so that they compile even when treated as c++, even if that's possible.
Maniacbug
Thanks for the link to the "open issue". I created one for this.
I agree it doesn't make much sense from an Arduino IDE point of view.
It is however hardly any work (I included the better twi.h) and results in better code quality.
Chris
The consequences are only visible for people writing their own tools on top of the Arduino library.
Basically you can not compile twi.c with the C++ compiler.
Further on I think it is a matter of taste on whether you prefer self containment and robustness or strict language layering (C code should not know about C++). Probably other arguments exist as well for both options.
Technically it is about the fact that C++ does name mangling and C does not. See Name mangling - Wikipedia for more info on name mangling.
You can easily find the ticked by following the create ticked link and searching for Wire.h
I downloaded your plugin (1.2.5.5) and changed my default "twi.h" for you listed code. Unfortunately, I am still not able to compile my project since I receive this error messages:
**** Build of configuration Release for project WB_MCU1 ****
make all
Building file: /Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c
Invoking: AVR Compiler
avr-gcc -I"/Applications/Arduino1.app/Contents/Resources/Java/hardware/arduino/cores/arduino" -I"/Applications/Arduino1.app/Contents/Resources/Java/hardware/arduino/variants/mega" -I"/Users/arduino/Documents/workspace/WB_MCU1" -I"/Users/arduino/Documents/Arduino1/libraries/RTClib" -I"/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire" -D__IN_ECLIPSE__=1 -DARDUINO=101 -DUSB_PID= -DUSB_VID= -Wall -Os -g -mmcu=atmega2560 -DF_CPU=16000000UL -MMD -MP -MF"Wire/utility/twi.d" -MT"Wire/utility/twi.d" -c -o "Wire/utility/twi.o" "/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c"
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c:115: error: conflicting types for 'twi_readFrom'
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.h:45: error: previous declaration of 'twi_readFrom' was here
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c:192: error: conflicting types for 'twi_writeTo'
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.h:46: error: previous declaration of 'twi_writeTo' was here
make: *** [Wire/utility/twi.o] Error 1