Pages: [1]   Go Down
Author Topic: Arduino library dev problem!  (Read 1010 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi
I wanted to use a little cpp source code in an arduino sketch, but it used the stack library from STL, so i decided to make my own just like it. Following the libraries tutorial on the arduino website i put together this:

Stack.h:
Code:
#ifndef STACK_H
#define STACK_H

template <class T>
class Stack {

    public:

        //Constructor
        Stack ();

        //Destructor
        ~Stack ();

        //Add an item to the stack
        void push (T item);

        //See the top item of the stack
        T top ();

        //Remove the top item of the stack
        void pop ();

        //Check if the stack is empty
        bool empty();

    private:

        struct element
        {
            T value;
            element *next;
        };

        struct main
        {
            int elements;
            element *top;
        };

        main * _main;
        element * _new, * _old;

        void deleteStack (element * el, int i);

};

#endif // STACK_H

Stack.cpp:
Code:
#include <Stack.h>

template <typename T>
Stack<T>::Stack ()
{
    _main = new main;
    _main.elements = 0;
}

template<typename T>
void Stack<T>::deleteStack (element * el, int i)
{
    if(i) deleteStack ( el.next , i-1 );
    delete el;
}

template<typename T>
Stack<T>::~Stack ()
{
    deleteStack ( _main.top, _main.elements-1 );
    delete _main;
}

template <typename T>
void Stack<T>::push(T item)
{
    _new = new element;
    _new.value = item;
    _new.next = _main.top;
    _main.top = _new;
}

template <typename T>
T Stack<T>::top()
{
    return _main.top.value;
}

template <typename T>
void Stack<T>::pop()
{
    _old =_main.top;
    _main.top = _main.top.next;
    delete _old;
}

template <typename T>
bool Stack<T>::empty()
{
    if(!_main.elements)return false;
    else return true;
}

But  it didn`t exactly work! i think that it is because of the template thing but i don`t know. The arduino IDE said this:
Code:
stack.cpp.o: In function `__static_initialization_and_destruction_0':
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:5: undefined reference to `Stack<int>::Stack()'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:5: undefined reference to `Stack<int>::~Stack()'
stack.cpp.o: In function `setup':
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:9: undefined reference to `Stack<int>::push(int)'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:10: undefined reference to `Stack<int>::top()'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:11: undefined reference to `Stack<int>::pop()'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:12: undefined reference to `Stack<int>::empty()'

Please help me! I really wan`t to make this work !!
Thank`s in advanced  smiley smiley smiley smiley-grin smiley-grin smiley-grin
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 220
Posts: 13846
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you post your testcode?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1515
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Seems to be a linker problem. The IDE did not find the Stack.cpp object code. In my own project I usually create a "utility" folder which contains my additional code. The utility folder seems to be analysed by the Arduino IDE. Indeed to me it is still an open question which are the search pathes of the Arduino IDE.

Oliver
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My guess is that you're running into this problem:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

I had never considered this; I've always included definitions inline in my templates.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is the test code;
 
Code:
#include <Stack.h>
Stack <int> st;

void setup ()
{
  st.push(5);
  int a = st.top();
  st.pop();
  bool b = st.empty();
}

void loop ()
{
 
}
All the files are in their proper places and are properly named. I also took a look at http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12 and tried a few things but they didn`t work. Any more ideas?
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you take the .h file from your original post, and add the function implementations that you have in the cpp file to make each function inline, you're almost there. e.g.

Code:
template <class T>
class Stack {

    public:

        //Constructor
        Stack ()
        {
          _main = new main;
          _main.elements = 0;
        }

Now, replace all of the periods with ->, because the data members you're addressing are pointers
Code:
        //Constructor
        Stack ()
        {
          _main = new main;
          _main->elements = 0;
        }

Now, you'll need an implementation of new and delete; you can add them at the end of your sketch
Code:
void * operator new( size_t size ) { return malloc( size ); }
void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }

Now, it will compile and link. If you have problems, try creating a new sketch and pasting the following, which is the new header file as described above, plus your test code from your most recent post and the new and delete implementations, all in one file.

Code:
void * operator new( size_t size ) { return malloc( size ); }
void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }

template <class T>
class Stack {

    public:

        //Constructor
        Stack ()
        {
          _main = new main;
          _main->elements = 0;
        }

        //Destructor
        ~Stack ()
        {
          deleteStack ( _main->top, _main->elements-1 );
          delete _main;
        }

        //Add an item to the stack
        void push (T item)
        {
          _new = new element;
          _new->value = item;
          _new->next = _main->top;
          _main->top = _new;
        }

        //See the top item of the stack
        T top ()
        {
            return _main->top->value;
        }

        //Remove the top item of the stack
        void pop ()
        {
            _old =_main->top;
            _main->top = _main->top->next;
            delete _old;
        }

        //Check if the stack is empty
        bool empty()
        {
            if(!_main->elements)return false;
            else return true;
        }

    private:
        struct element
        {
            T value;
            element *next;
        };

        struct main
        {
            int elements;
            element *top;
        };

        main * _main;
        element * _new, * _old;


        void deleteStack (element * el, int i)
        {
          if(i) deleteStack ( el->next , i-1 );
          delete el;
        }

};

Stack <int> st;

void setup ()
{
  st.push(5);
  int a = st.top();
  st.pop();
  bool b = st.empty();
}

void loop ()
{
 
}

Good luck!




Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, kerthyn,
Thanks for the help! I did as told me but it still doesn`t work this the header file, i think i got everything right.
Code:
#ifndef STACK_H
#define STACK_H

void * operator new( size_t size ) { return malloc( size ); }
void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }

template <class T>
class Stack {

    public:

        //Constructor
        Stack ()
        {
            _main = new main;
            _main->elements = 0;
        }

        //Destructor
        ~Stack ()
        {
            deleteStack ( _main->top, _main->elements-1 );
            delete _main;
        }

        //Add an item to the stack
        void push (T item)
        {
            _new = new element;
            _new->value = item;
            _new->next = _main->top;
            _main->top = _new;
        }

        //See the top item of the stack
        T top ()
        {
            return _main->top->value;
        }

        //Remove the top item of the stack
        void pop ()
        {
            _old =_main->top;
            _main->top = _main->top->next;
            delete _old;
        }

        //Check if the stack is empty
        bool empty()
        {
            if(!_main->elements)return false;
            else return true;
        }

    private:

        struct element
        {
            T value;
            element *next;
        };

        struct main
        {
            int elements;
            element *top;
        };

        main * _main;
        element * _new, * _old;

        void deleteStack (element * el, int i)
        {
            if(i) deleteStack ( el.next , i-1 );
            delete el;
        }
};

#endif // STACK_H

And these are the cimpiller errors:

Code:
In file included from stack.cpp:1:
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:4: error: declaration of 'operator new' as non-function
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:4: error: 'size_t' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h: In function 'void operator delete(void*)':
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:5: error: 'free' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h: In member function 'void Stack<T>::deleteStack(Stack<T>::element*, int) [with T = int]':
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:22:   instantiated from 'Stack<T>::~Stack() [with T = int]'
stack.cpp:5:   instantiated from here
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:75: error: request for member 'next' in 'el', which is of non-class type 'Stack<int>::element*'

Any thoughts ???
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nearly there!

There's no need for a stack.cpp; everything you need is in stack.h. Just delete stack.cpp from your sketch folder (keep a copy somewhere.) If you include stack.h in your main sketch file (or in whatever file needs stack<>), all should be well, except...

The new and delete functions should be defined only once (i.e. the implementation should only appear in one place.) You can put these in a separate file in your sketch folder (and the IDE will append that file to your sketch file before compilation,) or you can simply add them somewhere in your main sketch. You shouldn't need to declare these functions in your .h file, so remove those lines:
Code:
#ifndef STACK_H
#define STACK_H

// remove these next two lines
//void * operator new( size_t size ) { return malloc( size ); }
//void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }

template <class T>
...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When i put new and delete in the sketch it compiles, but not when they are in a file. BTW should i put anything else in that file or leave it just as it is?  :
Code:
void * operator new( size_t size ) { return malloc( size ); }
void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The iterations towards fixing this are unlikely to be of interest to others; check you private messages. When it's all working you can post the solution, which might be useful to others.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well finally this is the first working version: v1.0
with the help of Arduino forum user: kerthyn
You can download it from the bottom of the post!

Code:
Directory of c:\Program Files (x86)\Arduino\libraries\Stack

09.08.2011 ?.  16:52    <DIR>          .
09.08.2011 ?.  16:52    <DIR>          ..
09.08.2011 ?.  16:49               453 CppSupport.cpp
09.08.2011 ?.  16:48               583 CppSupport.h
10.08.2011 ?.  10:18    <DIR>          Examples
09.08.2011 ?.  16:52                94 keywords.txt
09.08.2011 ?.  16:51             1 738 Stack.h
               4 File(s)          2 868 bytes


Stack.h:
Code:
/*
Stack - library supporting the stack container.

Written by Simeon Dorelov
Date: 9 August 2011
*/

#ifndef STACK_H
#define STACK_H

#include <CppSupport.h>

template <class T>
class Stack {

    public:

        //Constructor
        Stack ()
        {
            _main = new main;
            _main->elements = 0;
        }

        //Destructor
        ~Stack ()
        {
            deleteStack ( _main->top, _main->elements-1 );
            delete _main;
        }

        //Add an item to the stack
        void push (T item)
        {
            _new = new element;
            _new->value = item;
            _new->next = _main->top;
            _main->top = _new;
            _main->elements++;
        }

        //See the top item of the stack
        T top ()
        {
            return _main->top->value;
        }

        //Remove the top item of the stack
        void pop ()
        {
            _old =_main->top;
            _main->top = _main->top->next;
            delete _old;
            _main->elements--;
        }

        //Check if the stack is empty
        bool empty()
        {
            if(!_main->elements)return true;
            else return false;
        }

        //Check the number of elements in the stack
        int size ()
        {
            return _main->elements;
        }

    private:

        struct element
        {
            T value;
            element *next;
        };

        struct main
        {
            int elements;
            element *top;
        };

        main * _main;
        element * _new, * _old;

        void deleteStack (element * el, int i)
        {
            if(i) deleteStack ( el->next , i-1 );
            delete el;
        }
};

#endif // STACK_H


CppSupport.h:
Code:
#ifndef CPPSUPPORT_H_INCLUDED
#define CPPSUPPORT_H_INCLUDED
#include <stdlib.h>
#ifdef __cplusplus
void * operator new( size_t size );
void operator delete( void * ptr );
extern "C"
{
#endif
  typedef int __guard __attribute__((mode (__DI__)));

  int __cxa_guard_acquire(__guard *);
  void __cxa_guard_release (__guard *);
  void __cxa_guard_abort (__guard *);
  int atexit(void (*)(void));    // support static objects
  void __cxa_pure_virtual(void); // support pure virtual classes
#ifdef __cplusplus
}  // extern "C"
#endif

#endif // CPPSUPPORT_H_INCLUDED

CppSupport.cpp
Code:
#include <stdlib.h>
#include "CppSupport.h"

void * operator new( size_t size ) { return malloc( size ); }
void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }

extern "C"
{
  int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
  void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
  void __cxa_guard_abort (__guard *) {};
  int atexit(void (*)(void)) {return 0;}
  void __cxa_pure_virtual(void) {};
}  // extern "C"

keywords.txt
Code:
Stack KEYWORD1
CppSupport KEYWORD1
top KEYWORD2
push KEYWORD2
pop KEYWORD2
empty KEYWORD2

Examples\ReverseSerial\ReverseSerial.pde:
Code:
#include <Stack.h>

Stack <char> st;


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

void loop ()
{
  if(Serial.available())
  {
    while(Serial.available())
      st.push(Serial.read());
    while(!st.empty())
    {
      Serial.print(st.top());
      st.pop();
    }
    Serial.println();
  }
}


* Stack.rar (1.86 KB - downloaded 11 times.)
Logged

Pages: [1]   Go Up
Jump to: