Added C++ binding.
authorFrank Mori Hess <fmhess@speakeasy.net>
Mon, 27 Aug 2007 21:46:35 +0000 (21:46 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Mon, 27 Aug 2007 21:46:35 +0000 (21:46 +0000)
Makefile.am
c++/Makefile.am [new file with mode: 0644]
c++/include/Makefile.am [new file with mode: 0644]
c++/include/comedilib.hpp [new file with mode: 0644]
configure.ac

index 6abfe2227c32553f416bb13382bba451fb01e10e..656a07d03739decf19375d701f1cb13ab7e66e0f 100644 (file)
@@ -1,6 +1,6 @@
 
 SUBDIRS = lib comedi_config man testing demo doc swig \
-       include etc scxi
+       include etc scxi c++
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = comedilib.pc
diff --git a/c++/Makefile.am b/c++/Makefile.am
new file mode 100644 (file)
index 0000000..b7f7189
--- /dev/null
@@ -0,0 +1,3 @@
+
+SUBDIRS = include
+
diff --git a/c++/include/Makefile.am b/c++/include/Makefile.am
new file mode 100644 (file)
index 0000000..4fda8ca
--- /dev/null
@@ -0,0 +1,3 @@
+
+include_HEADERS = comedilib.hpp
+
diff --git a/c++/include/comedilib.hpp b/c++/include/comedilib.hpp
new file mode 100644 (file)
index 0000000..4bce827
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+       A C++ binding for comedilib.  Requires the Boost C++ libraries.
+       Copyright (C) 2006-2007  Frank Mori Hess <fmhess@users.sourceforge.net>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU Lesser General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU Lesser General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _COMEDILIB_WRAPPER_HPP
+#define _COMEDILIB_WRAPPER_HPP
+
+#include <boost/shared_ptr.hpp>
+#include <comedilib.h>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+namespace comedi
+{
+       class subdevice;
+
+       class device    {
+       public:
+               device() {}
+               device(const std::string &device_file)
+               {
+                       this->open(device_file);
+               }
+               std::string board_name() const
+               {
+                       const char *name = comedi_get_board_name(comedi_handle());
+                       if(name == 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_board_name() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_board_name");
+                               throw std::runtime_error(message.str());
+                       }
+                       return name;
+               }
+               int command_test(comedi_cmd *cmd) const
+               {
+                       int retval = comedi_command_test(comedi_handle(), cmd);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_command_test() returned error.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_command_test");
+                               throw std::runtime_error(message.str());
+                       }
+                       return retval;
+               }
+               void command(comedi_cmd *cmd) const
+               {
+                       int retval = comedi_command(comedi_handle(), cmd);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_command() failed, return value=" << retval << " .";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_command");
+                               throw std::runtime_error(message.str());
+                       }
+               }
+               std::string default_calibration_path() const
+               {
+                       return comedi_get_default_calibration_path(comedi_handle());
+               }
+               void do_insn(comedi_insn *instruction) const
+               {
+                       int retval = comedi_do_insn(comedi_handle(), instruction);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_do_insn() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_do_insn");
+                               throw std::runtime_error(message.str());
+                       }
+               }
+               std::string driver_name() const
+               {
+                       const char *name = comedi_get_driver_name(comedi_handle());
+                       if(name == 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_driver_name() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_driver_name");
+                               throw std::runtime_error(message.str());
+                       }
+                       return name;
+               }
+               inline subdevice find_subdevice_by_type(int type, const subdevice *start_subdevice = 0) const;
+               int fileno() const
+               {
+                       int fd = comedi_fileno(comedi_handle());
+                       if(fd < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_fileno() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_fileno");
+                               throw std::runtime_error(message.str());
+                       }
+                       return fd;
+               }
+               unsigned n_subdevices() const
+               {
+                       int retval = comedi_get_n_subdevices(comedi_handle());
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_n_subdevices() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_n_subdevices");
+                               throw std::runtime_error(message.str());
+                       }
+                       return retval;
+               }
+               void open(const std::string &device_file)
+               {
+                       comedi_t *dev = comedi_open(device_file.c_str());
+                       if(dev == 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_open() failed, with device file name: \"" << device_file << "\".";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_open");
+                               throw std::runtime_error(message.str().c_str());
+                       }
+                       _comedi_handle.reset(dev, &comedi_close);
+               }
+       private:
+               friend class subdevice;
+
+               comedi_t* comedi_handle() const
+               {
+                       if(_comedi_handle == 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": device not open.";
+                               std::cerr << message.str() << std::endl;
+                               throw std::invalid_argument(message.str());
+                       }
+                       return _comedi_handle.get();
+               }
+
+               boost::shared_ptr<comedi_t> _comedi_handle;
+       };
+
+       class subdevice
+       {
+       public:
+               subdevice(const device &dev, unsigned subdevice_index):
+                       _device(dev), _index(subdevice_index)
+               {
+                       if(_index >= _device.n_subdevices())
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": invalid subdevice index.";
+                               std::cerr << message.str() << std::endl;
+                               throw std::invalid_argument(message.str());
+                       }
+               }
+               unsigned buffer_size() const
+               {
+                       int retval = comedi_get_buffer_size(comedi_handle(), index());
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_buffer_size() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_buffer_size");
+                               throw std::runtime_error(message.str());
+                       }
+                       return retval;
+               }
+               lsampl_t data_read(unsigned channel, unsigned range, unsigned aref) const
+               {
+                       lsampl_t value;
+                       int retval = comedi_data_read(comedi_handle(), index(), channel, range, aref, &value);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_data_read() failed, return value=" << retval << " .";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_data_read");
+                               throw std::runtime_error(message.str());
+                       }
+                       return value;
+               }
+               std::vector<lsampl_t> data_read_n(unsigned channel, unsigned range, unsigned aref, unsigned num_samples) const
+               {
+                       std::vector<lsampl_t> values(num_samples);
+                       int retval = comedi_data_read_n(comedi_handle(), index(), channel, range, aref, &values.at(0), values.size());
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_data_read_n() failed, return value=" << retval << " .";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_data_read_n");
+                               throw std::runtime_error(message.str());
+                       }
+                       return values;
+               }
+               void data_read_hint(unsigned channel, unsigned range, unsigned aref) const
+               {
+                       int ret = comedi_data_read_hint(comedi_handle(), index(), channel, range, aref);
+                       if(ret < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_data_read_hint() failed, return value = " << ret << " .";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_data_read_hint");
+                               throw std::runtime_error(message.str());
+                       }
+               }
+               void data_write(unsigned channel, unsigned range, unsigned aref, lsampl_t data) const
+               {
+                       int retval = comedi_data_write(comedi_handle(), index(), channel, range, aref, data);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_data_write() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_data_write");
+                               throw std::runtime_error(message.str());
+                       }
+               }
+               device dev() const {return _device;}
+               unsigned flags() const
+               {
+                       int retval = comedi_get_subdevice_flags(comedi_handle(), index());
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_subdevice_flags() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_subdevice_flags");
+                               throw std::runtime_error(message.str());
+                       }
+                       return retval;
+               }
+               unsigned index() const {return _index;};
+               unsigned max_buffer_size() const
+               {
+                       int retval = comedi_get_max_buffer_size(comedi_handle(), index());
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_max_buffer_size() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_max_buffer_size");
+                               throw std::runtime_error(message.str());
+                       }
+                       return retval;
+               }
+               unsigned n_channels() const
+               {
+                       int retval = comedi_get_n_channels(comedi_handle(), index());
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_n_channels() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_n_channels");
+                               throw std::runtime_error(message.str());
+                       }
+                       return retval;
+               }
+               unsigned n_ranges(unsigned channel = 0) const
+               {
+                       int retval = comedi_get_n_ranges(comedi_handle(), index(), channel);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_n_ranges() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_n_ranges");
+                               throw std::runtime_error(message.str());
+                       }
+                       return retval;
+               }
+               lsampl_t max_data(unsigned channel = 0) const
+               {
+                       lsampl_t value = comedi_get_maxdata(comedi_handle(), index(), channel);
+                       if(value == 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_maxdata() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_maxdata");
+                               throw std::runtime_error(message.str());
+                       }
+                       return value;
+               }
+               const comedi_range* range(unsigned channel, unsigned range_index) const
+               {
+                       comedi_range *cRange = comedi_get_range(comedi_handle(), index(), channel, range_index);
+                       if(cRange == 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_get_range() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_get_range");
+                               throw std::runtime_error(message.str());
+                       }
+                       return cRange;
+               }
+               void set_buffer_size(unsigned num_bytes) const
+               {
+                       int retval = comedi_set_buffer_size(comedi_handle(), index(), num_bytes);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_set_buffer_size() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_set_buffer_size");
+                               throw std::runtime_error(message.str());
+                       }
+               }
+               void set_max_buffer_size(unsigned num_bytes) const
+               {
+                       int retval = comedi_set_max_buffer_size(comedi_handle(), index(), num_bytes);
+                       if(retval < 0)
+                       {
+                               std::ostringstream message;
+                               message << __PRETTY_FUNCTION__ << ": comedi_set_max_buffer_size() failed.";
+                               std::cerr << message.str() << std::endl;
+                               comedi_perror("comedi_set_max_buffer_size");
+                               throw std::runtime_error(message.str());
+                       }
+               }
+       private:
+               comedi_t* comedi_handle() const {return dev().comedi_handle();}
+
+               device _device;
+               unsigned _index;
+       };
+
+       subdevice device::find_subdevice_by_type(int type, const subdevice *start_subdevice) const
+       {
+               unsigned start_index;
+               if(start_subdevice) start_index = start_subdevice->index();
+               else start_index = 0;
+               int subdev = comedi_find_subdevice_by_type(comedi_handle(), type, start_index);
+               if(subdev < 0)
+               {
+                       std::ostringstream message;
+                       message << __PRETTY_FUNCTION__ << ": failed to find subdevice of type " << type << " .";
+                       std::cerr << message.str() << std::endl;
+                       comedi_perror("comedi_find_subdevice_by_type");
+                       throw std::runtime_error(message.str());
+               }
+               return subdevice(*this, subdev);
+       }
+};
+
+#endif // _COMEDILIB_WRAPPER_HPP
index 829be3c119ba12334526374845e66953271a2c0d..7a0cad537a23961a1270b3acb46318fa0f53e8d2 100644 (file)
@@ -194,6 +194,8 @@ fi
 AC_CONFIG_FILES(
 Makefile
 comedi_config/Makefile
+c++/Makefile
+c++/include/Makefile
 etc/Makefile
 etc/pcmcia/Makefile
 etc/hotplug/Makefile