Hi,

I want to implement a "data acquisition package" equivalent to the one
present in Matlab. The main purpose is to access hardware with
measurement purposes (from Measurement Computing and Texas Instruments
for example). The idea is to release it as gpl and when finished
include it as an octave package. The needed drivers for measurement
computing devices (the ones I intend to implement first, as I have one
to make tests) are gpl and can be found in [1].

In order to do so, I must implement my own user defined types, as I
read in [2]. However, after googling a while, I haven't found much
documentation and examples on how programming my own types (besides
[2]). I'm not an expert programmer, and I don't know if I'm taking the
right approach.

The problem I have is that I want to create two classes, the first one
implements the instruments themselves (called analoginput in Matlab)
and the second one implements the channels with their corresponding
data. The first class must have a list of channels that can be added
through an "addchannel" call. Through a "trigger" call, the first
class, must also init the data adquisition and pass the data measured
to the channels.

My first draft looks like:

**********************************************************
***************** analoginput.h ************************
**********************************************************

#ifndef ANALOGINPUT_H
#define ANALOGINPUT_H

#include <iostream>
#include <octave/oct.h>
#include <octave/parse.h>
#include <octave/dynamic-ld.h>
#include <octave/oct-map.h>
#include <octave/oct-stream.h>
#include <octave/ov-base-scalar.h>
#include <string>

#include "channel.h"

using namespace std;

class AnalogInput : public octave_base_value
{
public:
    AnalogInput(void);
    AnalogInput(octave_value instr_val);
    AnalogInput(string type);

    ~AnalogInput(void);

    string*  get_str(void) const;

    void print(std::ostream& os, bool pr_as_read_syntax = false) const;
    Channel* addchannel() const;

    bool is_constant(void) const { return true; }
    bool is_defined(void) const { return true; }

private:
    string *objtype;

    // I will implement a list of channels here

    DECLARE_OCTAVE_ALLOCATOR
    DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
};

DEFINE_OCTAVE_ALLOCATOR(AnalogInput);
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(AnalogInput, "AnalogInput",
"AnalogInput");

#endif // ANALOGINPUT_H


**********************************************************
**************** analoginput.cpp **********************
**********************************************************

#include "analoginput.h"


AnalogInput::AnalogInput(void) : octave_base_value()
{
    objtype = new string("None");
}

AnalogInput::AnalogInput(octave_value instr_val) : octave_base_value()
{
    const octave_base_value& rep = instr_val.get_rep();
    objtype = ((const AnalogInput&) rep).get_str();
}

AnalogInput::AnalogInput(string type) : octave_base_value()
{
    objtype = new string(type);
}

AnalogInput::~AnalogInput(void)
{
}

string* AnalogInput::get_str(void) const
{
    return this->objtype;
}

void AnalogInput::print(std::ostream& os, bool pr_as_read_syntax) const
{
    os << "Instrument = " << *get_str() << endl;
}

Channel* AnalogInput::addchannel() const
{
    Channel* newChannel = new Channel();

    // Add the channel to the list here

    return newChannel;
}


DEFUN_DLD(analoginput, args, , "analoginput('adaptor')\n\
          Makes new instances of instrument objects")
{
    if(args.length() < 1){
        cout << "usage: analoginput('adaptor')\n";
        return octave_value();
    }

    AnalogInput *b = new AnalogInput(args(0).string_value());
    return octave_value(b);
}

DEFUN_DLD(addchannel, args, , "addchannel(AnalogInputObject, ID)\n\
          Adds a new analog channel to the adaptor")
{
    // This is yet to be implemented. Here I call the addchannel procedure,
    // and return the generated channel as a result.
    return octave_value(-1);
}


**********************************************************
******************** channel.h *************************
**********************************************************
#ifndef CHANNEL_H
#define CHANNEL_H

#include <iostream>
#include <octave/oct.h>
#include <octave/parse.h>
#include <octave/dynamic-ld.h>
#include <octave/oct-map.h>
#include <octave/oct-stream.h>
#include <octave/ov-base-scalar.h>
#include <string>

using namespace std;

class Channel : public octave_base_value
{
public:
    Channel(void);
    Channel(octave_value instr_val);
    Channel(string type);

    ~Channel(void);

    string*  get_str(void) const;

    void print(std::ostream& os, bool pr_as_read_syntax = false) const;

    bool is_constant(void) const { return true; }
    bool is_defined(void) const { return true; }

private:
    string *objtype;

    DECLARE_OCTAVE_ALLOCATOR
    DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
};

DEFINE_OCTAVE_ALLOCATOR(Channel);
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(Channel, "Channel", "Channel");

#endif // CHANNEL_H

**********************************************************
******************* channel.cpp ***********************
**********************************************************

#include "channel.h"

Channel::Channel(void) : octave_base_value()
{
    objtype = new string("None");
}

Channel::Channel(octave_value instr_val) : octave_base_value()
{
    const octave_base_value& rep = instr_val.get_rep();
    objtype = ((const Channel&) rep).get_str();
}

Channel::Channel(string type) : octave_base_value()
{
    objtype = new string(type);
}

Channel::~Channel(void)
{
}

string* Channel::get_str(void) const
{
    return this->objtype;
}

void Channel::print(std::ostream& os, bool pr_as_read_syntax) const
{
    os << "Instrument = " << *get_str() << endl;
}


DEFUN_DLD(channel, args, , "channel('adaptor')\n\
          Makes new instances of instrument objects")
{
    if(args.length() < 1){
        cout << "usage: channel('adaptor')\n";
        return octave_value();
    }

    Channel *b = new Channel(args(0).string_value());
    return octave_value(b);
}

**********************************************************

I compile the sources with the following commands:

mkoctfile channel.cpp
mkoctfile analoginput.cpp -o analoginput.oct
ln -s analoginput.oct addchannel.oct


The compilation has no errors. However, when I try to use the newly
defined objects in octave, if I try to create the analoginput I get
the following error:

error: /......./analoginput.oct: undefined symbol: _ZN7ChannelC1Ev

On the other hand, if I create any channel fist, and after that I
create an analoginput (with no relation with the channel created
before), I get no errors for the rest of the octave session.

Any ideas how should I fix this? Any suggestion on a better way to
implement the functions of this package, or anyone wanting to
contribute is welcome.

Thanks you for your help.

Regards,
Pablo

--

[1] ftp://lx10.tx.ncsu.edu/pub/Linux/drivers/
[2] http://wiki.octave.org/wiki.pl?CodaTypes

------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
Octave-dev mailing list
Octave-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/octave-dev

Reply via email to