How to use LiquidCrystal into an own library

Suppose I want to use LiquidCrystal arduino library through a library written by me. I don't want to use LiquidCrystal in the sketch program.

If I call LiquidCrystal on myLib.h like this:

#if(ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#include <inttypes.h>

class LiquidCrystal; // Instead of #include <LiquidCrystal.h>. Booth runs ok

#ifndef MyLib_h
#define MyLib_h

class MyLib{
    public:
        MyLib();
        ~MyLib();

    private:
        LiquidCrystal lcd(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
};

#endif

This compiles properly on the sketch program. I initialize LiquidCrystal constructor parameters because this library does not have a constructor without parameters, and if I call lcd like this:
'LiquidCrystal lcd;'
The following error appears: "field ‘lcd’ has incomplete type"

This is the simple skecth program, just to test MyLib:

#include <MyLib.h>

MyLib novaCpu = MyLib();

void setup(){
}

void loop(){
}

The problems appears with MyLib.cpp
If I try this on the constructor cpp, i.e.

...
#include <LiquidCrystal.h>
...
MyLib::MyLib(){
     lcd(1,2,3,4,5,6,7,8);
}
...

The following errors are received:

in .cpp: error: invalid use of incomplete type ‘struct LiquidCrystal’
in .h: error: forward declaration of ‘struct LiquidCrystal’

And If I try to write this, instead of previous definition:

...
#include <LiquidCrystal.h>
...
MyLib::MyLib(){
     LiquidCrystal lcd(1,2,3,4,5,6,7,8);
}
...

I have an only error in .cpp:

error: variable ‘LiquidCrystal lcd’ has initializer but incomplete type

What can I do? Thanks people

I don't want to use LiquidCrystal in the sketch program.

You have to. Get over it.

Hiding the use of libraries is not in keeping with open source, so it's not allowed.

Paul could you perhaps elaborate on your, typically, terse reply?
I'm not following it in the slightest.

Paul could you perhaps elaborate on your, typically, terse reply?

That was not typical. It was way terser that usual.

The IDE looks at the sketch, to find what to copy to the build directory. Any header file that is referenced in the sketch is copied, along with all the other files in the same folder that the header file is found in.

Include statements in other files do not result in any files being copied.

So, if the sketch does not include LiquidCrystal.h, the LiquidCrystal library is not available for use. When another library, such as OP's library wants to use LiquidCrystal, it is not available. Only libraries whose header files are included in the sketch are available for use.

There are arguments that can be made that this is not the best way, but suppose that other files are searched, and OP releases his library that uses two or three other libraries, and each of them uses 3 or 4 more. Tracking down missing libraries gets to be a nightmare, as does determining how much memory the libraries are using.

Seeing a sketch posted that includes one library doesn't usually raise low memory warnings. Seeing a sketch that uses 22 libraries does. If the header files are not all in the sketch, it becomes much more difficult to track them down.

Thank you for making the effort and taking the time.

Okay, I understand PaulS, very thankful

However I'm thinking that I already have an own library, which includes one library to use, this second library is not included on my sketch program, only first library has, and skecth compiles ok. I have to specify that all files are in the same directory, and this 'sub library' is also an own library, not an 'oficial' arduino library like LiquidCrystsal (this is the threat forum that you helped me to solve few days ago).

So anyway, this 'hack' is only possible with own libraries, not with another libraries?

Anyway, I'm working on it including myLib and LiquidCrystal in the sketch program.

As a private member on MyLib.h, I declare

LiquidCrystal lcd(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t);

just like the begining, and compiles ok.

In MyLib constructor, on MyLib.cpp, I write

lcd(d4, d5, d6, d7, a2, a3, a4, a5);

and compiles ok (d's are uint8_t variables)

But this 'lcd' is not able to use. Any liquid crystal functions make an error.

If I dont write anything about LiquidCrystal in .h, instead of write this in MyLig.cpp constructor:

LiquidCrystal lcd(d4, d5, d6, d7, a2, a3, a4, a5);
lcd.begin(40,4);

This complies so I also can use LiquidCrystal functions. But the problem is that this is not a class global variable, and if I try to call "lcd.print("hello");" in one of the MyLib.cpp class methods, I have the following error:

error: ‘lcd’ was not declared in this scope

So what can I do? I want a LiquidCrystal global variable. Thanks to all

I want a LiquidCrystal global variable.

You want a global variable or a member variable?

Any liquid crystal functions make an error.

Which is?

In MyLib constructor, on MyLib.cpp, I write

That doesn't create a global variable. That creates a local variable that goes out of scope when the constructor ends.

So what can I do?

Post ALL of your code, not just snippets.

PaulS:

I don't want to use LiquidCrystal in the sketch program.

You have to. Get over it.

Hiding the use of libraries is not in keeping with open source, so it's not allowed.

I would say that a person is "allowed" to write whatever kind of code he or she wants to.

Hiding code is certainly not in keeping with the concept of "open source" and should be discouraged, but it cannot be disallowed.

Hiding code is certainly not in keeping with the concept of "open source" and should be discouraged, but it cannot be disallowed.

You could argue that it shouldn't be disallowed. You can't argue that it can't be disallowed. Currently, it is.

Ok, so I post you the code:

MyLib.h

#if(ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#include <inttypes.h>

class LiquidCrystal; // Instead of #include <LiquidCrystal.h>. Booth runs ok

#ifndef MyLib_h
#define MyLib_h

class MyLib{
    public:
        MyLib();
        ~MyLib();

    private:
        LiquidCrystal lcd(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
};

#endif

sketch program (his goal is to test MyLib library)

#include <MyLib.h>
#include <LiquidCrystal.h>

MyLib libObject = MyLib();

void setup(){
}

void loop(){
}

Considering previous code, can you write a simple MyLib.cpp? I just want to undersant how to treat, in .cpp file, the lcd variable previously defined in .h. The goal is to create a LiquidCrystal member variable (I mean, LiquidCrystal object as a member of myLib class, to be used through myLib methods when myLib methods are called in sketch program)

It doesn't really matter what the cpp file looks like. You are creating lcd as a private member of the class. That contradicts with your stated goal of a global variable.

So, what is it you are trying to do?

MyLib libObject = MyLib();

Wrong. You NEVER call a constructor directly.
You create an instance of the class like:

MyLib libObject;

If you change the constructor to require arguments, you pass them to the instance, directly:
MyLib libObject(theArgsGoHere);

Or, you use pointers:

MyLib *libObject = new MyLib();

or

MyLib *libObject = new MyLib(theArgsGoHere);

(Just exactly like LiquidCrystal objects are created.)

The goal is to create a LiquidCrystal member variable (I mean, LiquidCrystal object as a member of myLib class, to be used through myLib methods when myLib methods are called in sketch program)

My goal is just that: having a LiquidCrystal object to be used by myLib methods, when myLib methods are called in sketch program (using the libObject object previously created).

I write an example but using an uint8_t type isntead of a LiquidCrystal type, to show you what I want to do, because whit a simple type runs ok:

Here is the code:

Sketch program (thanks for the libObject call specification)

#include <MyLib.h>
#include <LiquidCrystal.h>

MyLib libObject;

void setup(){
  Serial.begin(9600);
  libObject.methodData();
}

void loop(){
}

MyLib.h:

#include <inttypes.h>

class LiquidCrystal; // Instead of #include <LiquidCrystal.h>. Booth runs ok

#ifndef MyLib_h
#define MyLib_h

class MyLib{
    public:
        MyLib();
        ~MyLib();
        void methodData();

    private:
        uint8_t data;
        LiquidCrystal lcd(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
};

#endif

MyLib.cpp:

#if(ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#include <inttypes.h>
#include <LiquidCrystal.h>

MyLib::MyLib(){
	data = 10;
}

void MyLib::methodData(){
	data = 50;
}

MyLib::~MyLib(){
}

There is no problem with 'data' as private member. It can be used in 'methodData()' as a recognized declaration in this scope. My question is: Can I do the same with the 'lcd' private variable, instead of 'data'? In case I can, how I have to declare and definite lcd variable? In case it's not possible, what could I do?

Thanks for the patience

Can I do the same with the 'lcd' private variable,

Of course.

I'm failing to see what the problem is. If the code you posted compiles and executes, then there IS an instance of LiquidCrystal being created, so you could add lcd.print() to MyLib::methodData() and it should work,

If not, you'll need to tell us exactly what happens.

Bonetky:
Suppose I want to use LiquidCrystal arduino library through a library written by me. I don't want to use LiquidCrystal in the sketch program.

Simple, just copy the LiquidCrystal library source code into your own library. But you have to respect the open source license agreement if/when you distribute your own library.

I'm failing to see what the problem is

I want to do exactly the same as uint8_t data variable, this is: I want to declare a 'lcd' private variable in MyLib.h (already done)

LiquidCrystal lcd(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);

then I want to associate this 'lcd' variable with 8 uint8_t values in MyLib.cpp constructor, call 'lcd.begin(40,4)' at the follow line, and then I want to be able to use this lcd variable in 'methodData()' just like we already use 'data' variable in the same method, changing her value (data = 50)

I give you the cod files.

sketch file:

#include <MyLib.h>
#include <LiquidCrystal.h>

MyLib libObject;

void setup(){
  Serial.begin(9600);
  libObject.methodData();
}

void loop(){
}

MyLib.h:

#include <inttypes.h>

class LiquidCrystal; // Instead of #include <LiquidCrystal.h>. Booth runs ok

#ifndef MyLib_h
#define MyLib_h

class MyLib{
    public:
        MyLib();
        ~MyLib();
        void methodData();

    private:
        uint8_t data;
        uint8_t d1;
        uint8_t d2;
        uint8_t d3;
        uint8_t d4;
        uint8_t d5;
        uint8_t d6;
        uint8_t d7;
        uint8_t d8;
        LiquidCrystal lcd(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
};

MyLib.cpp:

#if(ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#include <inttypes.h>
#include <LiquidCrystal.h>

MyLib::MyLib(){
	data = 10;
        d1 = 1;
        d2 = 2;
        d3 = 3;
        d4 = 4;
        d5 = 5;
        d6 = 6;
        d7 = 7;
        d8 = 8;
        lcd(d1, d2, d3, d4, d5, d6, d7, d8);
}

void MyLib::methodData(){
	data = 50;
}

MyLib::~MyLib(){
}

First of all, I don't know if this 'lcd(d1, d2, d3, d4, d5, d6, d7, d8);' definition is the correct way to define 'lcd(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t);'. But I can assure you that this code compiles

Well, now the problems appears:
Problem1: if I add this line after 'lcd(d1,d2,d3,d4,d5,d6,d8)' line, still in MyLib.cpp constructor:

lcd.begin(40,4);

then

error: ‘((MyLib*)this)->MyLib::lcd’ does not have class type

about this error, I'm sure that I can't create 'lcd' variable, in MyLib.h, like this:

LiquidCrystal lcd;

instead of 'LiquidCrystal lcd(args...)' because in that case, I have an error at this line:

error: field ‘lcd’ has incomplete type

Problem 2: Considering the previously listed files, If I add this line in methodData():

lcd.print("hello");

I have exactly the same error as shown in Problem 1, with 'lcd.begin(40,4)' line

error: ‘((MyLib*)this)->MyLib::lcd’ does not have class type

And I'm still unable to create a LiquidCrytal private variable and then using it on constructor and methodData in MyLib.cpp. Meanwhile, uint8_t data private variable keep working well

I want to specify that error listed in Problem 2: is due to lcd.print line, not lcd.begin. Lcd.begin line does not exist to this test

The lcd instance in your class is not being properly defined. The arguments are not named or valued.

You need to declare that lcd is an instance of the LiquidCrystal class, using a pointer.

LiquidCrystal *lcd;

In the constructor for your class, you actually need to construct the lcd object.

If you are hard-coding pin numbers in the constructor for your class, instead of passing values to the constructor, it doesn't make sense to make the project so complicated.

Okey, so I declare 'LiquidCrystal *lcd' in MyLib.h private variables instead of 'LiquidCrystal lcd(args..)', and it compiles

Now, how can I define lcd arguments in MyLib.cpp constructor? I tried with

lcd = new LiquidCrystal(d1, d2, d3, d4, d5, d6, d7, d8);

and it complies too, but if I call
lcd.begin(40,4); at the next line, I have this error:

request for member ‘begin’ in ‘((MyLib*)this)->MyLib::lcd’, which is of non-class type ‘LiquidCrystal*’

And another failed tries, for example:

Trying with

lcd(d1, d2, d3, d4, d5, d6, d7, d8);

We have this error

error: ‘((MyLib*)this)->MyLib::lcd’ cannot be used as a function

Trying with

lcd = LiquidCrystal(d1, d2, d3, d4, d5, d6, d7, d8);

We have this error

error: cannot convert ‘LiquidCrystal’ to ‘LiquidCrystal*’ in assignment

Trying with

LiquidCrystal lcd(d1, d2, d3, d4, d5, d6, d7, d8);

It compiles, but we are creating a new lcd local variable, not defining our private lcd variable from MyLib.h

  1. What is your objection to putting #include "LiquidCrystal.h" in MyLib.h?

  2. If you do put #include "LiquidCrystal.h" in MyLib.h then you can initlize lcd like this. In the MyLib.h file:

LiquidCrystal lcd;

In MyLib.cpp file:

MyLib::MyLib() : lcd(1,2,3,4,5,6,7,8) {}
}

You don't need variables d1, d2 etc. unless you are sharing the pins with something else and need to remember what the pin number are.

  1. Don't try to call lcd.begin() in the constructor. If necessary, add a begin() method to MyLib and call lcd.begin() from that.