From d720e88a52f7a4526ac2edb4a9d5bc6ad25cd302 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Mon, 27 Aug 2007 21:46:35 +0000 Subject: [PATCH] Added C++ binding. --- Makefile.am | 2 +- c++/Makefile.am | 3 + c++/include/Makefile.am | 3 + c++/include/comedilib.hpp | 375 ++++++++++++++++++++++++++++++++++++++ configure.ac | 2 + 5 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 c++/Makefile.am create mode 100644 c++/include/Makefile.am create mode 100644 c++/include/comedilib.hpp diff --git a/Makefile.am b/Makefile.am index 6abfe22..656a07d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 index 0000000..b7f7189 --- /dev/null +++ b/c++/Makefile.am @@ -0,0 +1,3 @@ + +SUBDIRS = include + diff --git a/c++/include/Makefile.am b/c++/include/Makefile.am new file mode 100644 index 0000000..4fda8ca --- /dev/null +++ b/c++/include/Makefile.am @@ -0,0 +1,3 @@ + +include_HEADERS = comedilib.hpp + diff --git a/c++/include/comedilib.hpp b/c++/include/comedilib.hpp new file mode 100644 index 0000000..4bce827 --- /dev/null +++ b/c++/include/comedilib.hpp @@ -0,0 +1,375 @@ +/* + A C++ binding for comedilib. Requires the Boost C++ libraries. + Copyright (C) 2006-2007 Frank Mori Hess + + 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 +#include +#include +#include +#include +#include +#include + +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_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 data_read_n(unsigned channel, unsigned range, unsigned aref, unsigned num_samples) const + { + std::vector 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 diff --git a/configure.ac b/configure.ac index 829be3c..7a0cad5 100644 --- a/configure.ac +++ b/configure.ac @@ -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 -- 2.26.2