Pages: [1] 2   Go Down
Author Topic: Using libraries in libraries  (Read 1202 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am attempting to write a library to simplify some specific I2C related tasks. How can I #include Wire.h in the header file of my library? I don't want to have to #include Wire.h in the main sketch, and I need full access to the functions in Wire.h from my header file (and .cpp file). I have tried many things and googled for about an hour, and I haven't found anything that seems to work.
Logged

Salem, Oregon
Offline Offline
Sr. Member
****
Karma: 7
Posts: 310
Friends don't let friends use Strings
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I don't know if this is the right way or not, but I took a look at one of the Dallas Temperature IC libraries (from http://milesburton.com/Dallas_Temperature_Control_Library) which also uses OneWire.

Apparently the author has simply included a copy of the OneWire libraries in the same folder as his library, and then simply includes the file:

Code:
#include "NewOneWire.h"

(he's using a modified version of the one-wire library)

Have you tried doing that?

Brad (KF7FER)

EDIT: Fixed broken link
« Last Edit: February 15, 2012, 10:25:34 pm by Brad Burleson » Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well that does seem to work, although it's not right.

Another problem: I tried declaring variables in the header file, but it complains about "multiple definition of" them in the .cpp file, and I can assure you I didn't re-declair them in the .cpp file (although I did use them in functions).
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay, so now it compiles without errors. I had to add "static" to all the variables. Why is this?

And back to the original problem, how do I properly link to the Wire library?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You shouldn't have variables in .h files, or you will get multiple declarations. You can put "extern" variables, and then have the real variables in a .cpp file. Making them static just gives multiple copies of variables of the same name, something you probably don't want.

I think the Wire library can be problematic, from memory of past experiences. The way the IDE copies stuff hither and thither it seems to need an include of Wire.h in the main sketch, seemingly when you shouldn't need it. Or at least it did under the 0022 version of the IDE.
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, you're saying I should declare all my library-specific variables in the .cpp file, instead of .h?

What I am doing now, is using #include <Wire.h> in the main sketch, and #include <C:\Program Files (x86)\arduino-1.0\libraries\Wire/Wire.h> in the header file. Why can't they fix the issues with the files? This is certainly not the only issue.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So, you're saying I should declare all my library-specific variables in the .cpp file, instead of .h?

Yes, the general technique is to put extern foo in the .h file and actually declare foo in the .cpp file in your library.

For example, HardwareSerial.

In HardwareSerial.h:

Code:
  extern HardwareSerial Serial;  // so it can be referenced in lots of places

In HardwareSerial.cpp:

Code:
// actually create the object:
  HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X);

Quote
Why can't they fix the issues with the files?

There are a few issues which "they" have not addressed just yet.
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay, so what added scope would foo have if I did extern foo in the header (or what scope would foo have without putting it in the header file with extern foo)?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Without putting foo in the .h file it will have scope in the compilation unit in which it resides (ie. the .cpp file).

If it is in the .h file (with extern) it will have scope inside all the compilation units that include it. (In other words, they will get the same foo).

If you make foo static you will get a different foo in each compilation unit. Which isn't particularly useful, I suggest.
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Making it "extern" basically says "the linker will sort it out".

But if you never have a "non extern" foo then the linker will say "I couldn't find the *real* foo" and the link will fail.
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, you're saying that if I want the variables used in .cpp to be global to the entire sketch, I need to prototype them using extern in the header?

And if I don't want them to be global to the entire sketch, I don't prototype them with extern in the header?

In this particular case I don't want them to (at least they certainly don't have to) have scope beyond the library, so is it safe for me to only mention them in .cpp? For what little testing I have done so far, I would say it's working how I want it to without using extern in the header.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

And if I don't want them to be global to the entire sketch, I don't prototype them with extern in the header?

Absolutely. And to labour the point, make them static in the .cpp file. If you make a variable static, it can't be "externed" because static says "this is local to this compilation unit".
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a million for the help! Other than the #include Wire thing, it's working exactly how I want it to smiley-lol
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So everything is still working fine, other than the #include file stuff...

I have a new problem. I built a library that involves timer interrupts. I #include <avr/io.h> and <avr/interrupt.h> from the main sketch, and that work fine (although I would like them to be automatically #include d from the library .h file). I have 4 functions that I don't want public, and I have 3 that I need public (public, as in accessible from the main sketch). I want to use a Class with Public: and Private:, but I don't know how to make the ISR be able to access functions in a class.

Would it be best to have all the functions that ISR ever calls, not be in a class (but still private somehow), and put all the sketch-accessible functions in the Class?

It would be ideal to be able to have the ISR call functions from inside a class. Is that possible?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 632
Posts: 50182
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It would be ideal to be able to have the ISR call functions from inside a class. Is that possible?
Sure. But, for which instance of the class?
Logged

Pages: [1] 2   Go Up
Jump to: