Как вызвать библиотеку из библиотеки?
- Войдите на сайт для отправки комментариев
Ср, 11/11/2015 - 15:31
Коллеги,
есть две библиотеки: lib1.h и lib2.h
вот думаю как можно вызвать методы lib1.h из lib2.h.
Пытался это сделать но прикомпиляции пишется ошибка, что он не видит lib1.
Как это можно сделать?
Если Вам не нужно вызывать из .cpp файла, а достаточно из .h, то это совсем просто. Сделайте так, чтобы в основном скетче include на тот .h файл в котором вызывается стоял ПОСЛЕ include того файла из которого вызывается. Если надо, могу выложить пример.
Кстати, если вызывать надо из .cpp файла, то тело этой функции (в которой есть такой вызов) всегда можно перенести в .h файл.
Да примерчик бы не помешал.....
Я попробовал это сделать теперь он говорить что идет редефинишн - переопределение.
ТО есть мы двараза файл указали ф библиотеке вызвали lib1 и в основном коде.
НО у меня основаная сложность в том как в коде смой библиотеки вызвать другую.
Какой синтаксис, надо ли использовать new ведь по сути в бибилотеке мы создвем новый экземпляр класса другой билиотеки?
А где тогда хранить сами файлы библиотек в папке libraries?
В каталоге с библиотеками смотрю файл SpacebrewYun.h, вижу строку #include <Bridge.h>
С new и всем остальным никаких проблем - если .h файл того, что мы создаём, видим из того места, где создаём, то все нормально.
Как я уже писал - всё гораздо проще, если весь текст библиотеки находится в .h файле (с файлом .cpp сложнее). Поэтому давайте сделаем так. Сейчас я Вам дам пример как всё сделать для случая, когда всё находится в .h файле. Посмотрите, запустите, убедитесь, что нормально компилируется и т.п.
Затем, если Вы сами не знаете, то я объясню как любую функцию из .cpp файла перенести в .h файл ничего при этом не сломав. И, наконец, если схранится потребность, то тогда уж поговорим как быть, если очень хочется всё держать таки в .cpp файле.
Итак,
1. имеется библиотека VoltageRange - это просто пара чисел и определённая для неё операция "==". Операция определена так, что если сравнить экземпляр VoltageRange с целым числом, то "истина" получится, если число попадает в интервал, заданный парой чисел VoltageRange и "ложь" - если не попадает.
2. Имеется библиотека ResistiveKeyboard, которая содержит несколько диапазонов (типа VoltageRange) и имеет единственный метод - keyPressed(int pin). Метод читает аналоговый пин и проверяет попало ли значение считанное с пина в один из интервалов VoltageRange. Если попало - возвращает номер интервала (считая с 1), а если не попало ни в один - возвращает 0.
3. имеется скетч, который создаёт клавиатуру с четырьмя кнопками и в loop проверяет не нажата ли какая-нибудь кнопка и, когда нажата, печатает номер кнопки.
Файлы расположены стандартно:
MySkethes\kaka\kaka.ino - файл скетча
MySkethes\libraries\VoltageRange\VoltageRange.h - файл библиотеки
MySkethes\libraries\ResistiveKeyboard\ResistiveKeyboard.h - файл библиотеки
Это важно. Библиотека VoltageRange используется в ResistiveKeyboard, поэтому VoltageRange определена выше. Когда она потребуется для ResistiveKeyboard, она уже будет определена. Если написать include наоборот, то VoltageRange не будет доступна для ResistiveKeyboard
Смотрите. Попробуйте добавить в ResistiveKeyboard new VoltageRange всё должно работать. Убедитесь, что всё поняли и ответьте на вопрос "хватит ли Вам этого".
Ну, теперь, собственно, тексты.
kaka.ino
#include <VoltageRange.h> #include <ResistiveKeyboard.h> #define KEYBOARD_PIN 1 static VoltageRange ranges[] = { VoltageRange(0,256), VoltageRange(256, 512), VoltageRange(512,768), VoltageRange(768,1024) }; static const int8_t TotalRanges = sizeof(ranges)/sizeof(ranges[0]); static ResistiveKeyboard keyboard(ranges, TotalRanges); void setup(void) { } void loop(void) { const int8_t key = keyboard.keyPressed(KEYBOARD_PIN); if (key > 0) { Serial.print("Key pressed: "); Serial.println(key); } }VoltageRange.h
#ifndef VOLTAGERANGE_H #define VOLTAGERANGE_H #include <arduino.h> class VoltageRange { public: VoltageRange (const int minV, const int maxV) { m_min = minV; m_max = maxV; } friend const bool operator == (const VoltageRange & r, const int voltage) { return (voltage >= r.m_min) && (voltage < r.m_max); } friend const bool operator == (const int voltage, const VoltageRange & r) { return r == voltage; } private: int m_min, m_max; }; #endif // VOLTAGERANGE_HResistiveKeyboard.h
#ifndef RESISTIVEKEYBOARD_H #define RESISTIVEKEYBOARD_H #include <arduino.h> class ResistiveKeyboard { public: ResistiveKeyboard (VoltageRange * ranges, const int8_t TotalRanges) { m_ranges = ranges; m_total = TotalRanges; } const int8_t keyPressed(const int8_t pin) const { const int volts = analogRead(pin); for (short i=0; i < m_total; i++) { if (m_ranges[i] == volts) return i+1; } return 0; } private: VoltageRange * m_ranges; int8_t m_total; }; #endif // RESISTIVEKEYBOARD_HЧуть не забыл! Если будете запускать, добавьте там стандартную инициализацию сериала и т.п. - я это убрал, чтобы не загромождать код.
ЕвгенийП, благодарю за развернутое пояснение возможно данный конкретный пример и будет работать, но я никак не могу уловить логику действий....
Вот например:
1. Создаем мы VoltageRange в RestrictiveKeyboard. А где new VoltageRange.
2. В каком синтаксисе писать: VoltageRange VR = new VoltageRange или VoltageRange:VR?Опять же если несколько экземпляров типа VoltageRange то всетаки как то надо создать экземпляр.
3.Взять за правило что если это делается в h файле тогда никаких include он типа и так все видит?
4.Вообще на каком языке мы это все пишем: ( С,С++,'Поскаль' на крайняк:) )?
По факту у меня он снова жалуется на редефинишен, мол я перереопределяю уже заранее определенный класс.
#ifndef RESISTIVEKEYBOARD_H #define RESISTIVEKEYBOARD_H #include <arduino.h> #include "VoltageRange.h" class ResistiveKeyboard { public: ResistiveKeyboard (VoltageRange * ranges, const int8_t TotalRanges) { m_ranges = ranges; m_total = TotalRanges; VoltageRange * vr = new VoltageRange(0,1024); delete vr; } const int8_t keyPressed(const int8_t pin) const { const int volts = analogRead(pin); for (short i=0; i < m_total; i++) { if (m_ranges[i] == volts) return i+1; } return 0; } private: VoltageRange * m_ranges; int8_t m_total; }; #endif // RESISTIVEKEYBOARD_HПочему то эта конструкция не работает. Вот пример: Lib2: #if defined(ARDUINO) && ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif class Lib2 { public: Lib1 * Lib1obj_1; Lib1 * Lib1obj_2; Lib2() { Lib1obj_1 = new Lib1(); Lib1obj_2 = new Lib1(); } int MethodLib2() { return Lib1obj_1.MethodLib1() + Lib1obj_2.MethodLib1(); } };(Почему то код вставляется только один раз и только в начале.)
#if defined(ARDUINO) && ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif class Lib1 { public: int * valueLib1; Lib1() { valueLib1 = 0; } int * MethodLib1() { return valueLib1++; } };Я не понял. Что значит не работает? Чтоговорит? Что значит вставляется один раз и в начале. Это что за кусок текста? Он живёт в библиотеке или в основном скетче? Ничего не понял.
#if defined(ARDUINO) && ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif class Lib1 { public: int valueLib1; Lib1() { valueLib1 = 0; } int MethodLib1() { return valueLib1++; } };#include <Lib1.h> Lib1 LB11; Lib1 LB12; void setup() { Serial.begin(9600); } void loop() { Serial.println(LB11.MethodLib1()+LB12.MethodLib1()); }Вот в таком варианте: когда LIB1 вызывается из ino файла все работает.
#include <Lib1.h> #include <Lib2.h> Lib2 LB; void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: LB.MethodLib2(); // Serial.println(LB.MethodLib2()); }#if defined(ARDUINO) && ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif class Lib1 { public: int * valueLib1; Lib1() { valueLib1 = 0; } int * MethodLib1() { return valueLib1++; } };#if defined(ARDUINO) && ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif class Lib2 { public: Lib1 * Lib1obj_1; Lib1 * Lib1obj_2; Lib2() { Lib1obj_1 = new Lib1(); Lib1obj_2 = new Lib1(); } int * MethodLib2() { return (Lib1obj_1 -> MethodLib1()); } };Вот в таком варианте когда первая библиотека вызывается не в ino файле а в другой беблиотеку все тоже работает.
НО!
Во втором варианте необходимо обязательно указывать указатели *, обозначая переменную как ссылочный тип и осуществлять доступ к методам через указатели -> иначе не работает.
Во втором варианте также не получается отобразить результат возвращаемого методом значения так как компилятор не может сделать конвертацию типов из int в int*, не получается так же сложить 2 результата возвращаемых 2-мя методами разных обьектов.
В итоге вопрос концептуальный:
Создается ли в первом варианте 2 разных обьекта?
Не могу понять всетаки синтаксис: в первом варианте не нужно указывать ссылочные типы а во втором нужно без этого не работает?
Что правильнее?
ЗЫ: когда добавляю на форум топики код получается добавить только один раз (2 разных кода не добввляются) и он всегда помещается в начале топика.
Во втором варианте необходимо обязательно указывать указатели *, обозначая переменную как ссылочный тип и осуществлять доступ к методам через указатели -> иначе не работает.
Вот Вы говорите "не работает", но при этом не приводите ТОГО вариаанта, который собственно не работает и не приводите сообщений компилятора. Вместо неработающего варианта, Вы пишете "надо обязательно ..., а иначе ...". Но я же не вижу, как именно Вы добились, чтобы не работало. Как я могу догадаться в чём проблема?
Вот давайте спокойно и методично: дайте мне три файла (ino и две бибилиотеки), которые не компилируются и приведите сообщение компилятора.
Если не умеете постить три файла, соедините в один, только комментариями отделите.
#if defined(ARDUINO) && ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif class Lib1 { public: int * valueLib1; Lib1() { valueLib1 = 0; } int * MethodLib1() { return valueLib1++; } };Это что? Вы описали УКАЗАТЕЛЬ на int. Присвоили УКАЗАТЕЛЮ 0, а затем проводите арифметику с этим УКАЗАТЕЛЕМ! Вы именно этого хотели?