Using C and Arduino libraries

Hello,

I would like to use the c++ arduino libraries while writing my own code in c.
What's the best way to do that?

Let's say I had vector.h and vector.c written in c-syntax.
How do I use these in arduino-sketch.ino?

So far I have tried including this vector.h in my sketch, but as a result avr-gcc will only complain that the vector functions are not defined. Probably meaning that it can't find the .c files that are in the same directory.

The compiler is expecting to find .cpp files not .c files

Depending on how the library is written there is a chance that it will work if you rename the .c files to .cpp. Try it and see.

Ok, that's working.

The thing just is that it's not c++, but c. That's why it still should be .c.
So, is it possible to use avr-gcc on .c files and avr-g++ on .cpp files?

Yes. By default, the compiler will infer the language automatically from the file extension.

C++ is a super set of c. Things where added to C but nothing was taken away.

Maek

Now it's working.

I have a c project with cmake building (developing and testing on pc before uploading).

<c-project>
---- build
---- src
---- CMakeLists.txt

I added extern "C" {} with ifdef __cplusplus to all my c headers.
I also created a symbolic link of src named as a Arduino project to my Arduino project path: ln -s ~/Arduino/
Then created a entry file for Arduino: touch ~/Arduino//.ino and added the setup and loop functions.

Now I can write my code as a civilized person using a proper text editor and testing stuff out on pc before switching to Arduino IDE to upload my work.

Just for information, although you are required to implement setup() and loop() functions, there's nothing stopping you from implementing them in .c or .cpp files if you prefer. Although you are required to have a .ino file with the same name as the sketch, you aren't obliged to put anything in it.

holmes4:
C++ is a super set of c. Things where added to C but nothing was taken away.

They aren't fully compatible, though (not all valid 'c' is valid c++), which I think is the issue here.

not all valid 'c' is valid c++

Can you cite a specific example?

PaulS:

not all valid 'c' is valid c++

Can you cite a specific example?

There are some differences in the handling of implicit type casts. In 'C' you can implicitly cast a void pointer to any other type of pointer - in C++ you can't.

C++ introduces some new keywords. Any identifiers in 'C' which happen to use the new keywords would be invalid C++.

In C++ you are required to prototype functions before you can call them. In 'C' is is not required, although it is recommended.

C++ implicitly defines a type when you declare a struct. 'C' doesn't. This causes some subtle differences in the interpretation of code where variables and types use the same names.

I'm sure this isn't a comprehensive list. Bottom line is that just because the C++ language is a superset of the 'C' language, does not imply that all valid 'C' is also valid C++ or that a given piece of code will produce the same behaviour in both languages.

In 'C' you can implicitly cast a void pointer to any other type of pointer - in C++ you can't.

But, you can explicitly cast a void pointer to anything you like.

C++ introduces some new keywords. Any identifiers in 'C' which happen to use the new keywords would be invalid C++.

Well, OK, you got me there.

In C++ you are required to prototype functions before you can call them. In 'C' is is not required, although it is recommended.

In C, the function signature has to be known before the function is called, whether through a function prototype or the actual function. I don't see this as a logical distinction.

C++ implicitly defines a type when you declare a struct. 'C' doesn't. This causes some subtle differences in the interpretation of code where variables and types use the same names.

When has that ever been a good idea?

Bottom line is that just because the C++ language is a superset of the 'C' language, does not imply that all valid 'C' is also valid C++ or that a given piece of code will produce the same behaviour in both languages.

If you follow recommended practices in C, the code will compile, link, and run the same using a C compiler or a C++ compiler.

PaulS:
If you follow recommended practices in C, the code will compile, link, and run the same using a C compiler or a C++ compiler.

It's possible to write 'C' code which will compile and run as C++ code, but I think you're understating the differences between them. You seem to be implying that the potential incompatibilities can be ignored, and I don't think that's right.

PeterH:

PaulS:
If you follow recommended practices in C, the code will compile, link, and run the same using a C compiler or a C++ compiler.

It's possible to write 'C' code which will compile and run as C++ code, but I think you're understating the differences between them. You seem to be implying that the potential incompatibilities can be ignored, and I don't think that's right.

PeterH is right. The things he mentioned are reasonably common in C, for the most part.
For example:

In 'C' you can implicitly cast a void pointer to any other type of pointer - in C++ you can't.

How many times have I seen:

int* ptr = malloc(sizeof(int) * 5);

It's not hard to change it to the following:

int* ptr = (int*) malloc(sizeof(int) * 5);

But it does require a change to the code, so off the bat, it wouldn't compile.

But let's say you do write your code so that it's C++ compatible, and it does compile; there are still differences between the two languages which can lead to logical errors. For example, one thing which might trip you up is that character literals in C are actually ints. In C++, they're chars. It's a subtle difference, but in the right situation, it could be important, because they'd have different sizes. You just have to be careful when you're porting something, that's all we're saying Paul.

Let's put it this way: While I recognize the OP is a notable exception to this argument, few people here are going to write C code which is written explicitly to be compatible with C++. Why? Because if they wanted that, they'd probably just actually use C++, and just avoid using features like classes. What would be stopping them? It compiles to machine code, right? So the main reason to have this discussion is if you're porting older libraries from C to C++, and if that's the case, then I can all but guarantee that without much looking you'll quickly run into many of the issues that PeterH has discussed in his previous posts here. I've seen people bypass variable initialization using gotos and everything in certain pieces of code, which (thankfully) will not compile at all in C++.

However, if your intention is to write C code that is compatible with C++, then it is certainly not too difficult to do, Just be aware of the differences, that's all.