Add C++ bindings.

This commit is contained in:
Martin Ling 2014-07-17 18:39:49 +01:00
parent 00ebcbf48a
commit c23c8659b8
11 changed files with 2077 additions and 1 deletions

5
.gitignore vendored
View File

@ -43,6 +43,11 @@ Makefile.in
# KDevelop project files
*.kdev4
# Files generated by building C++ bindings
bindings/cxx/libsigrok.xml
bindings/cxx/include/libsigrok/enums.hpp
bindings/cxx/enums.cpp
# Files generated by building Python bindings
bindings/python/dist/
bindings/python/build

View File

@ -379,6 +379,33 @@ tests_check_main_LDADD = $(top_builddir)/libsigrok.la @check_LIBS@
endif
if BINDINGS_CXX
lib_LTLIBRARIES += bindings/cxx/libsigrokxx.la
bindings_cxx_libsigrokxx_la_SOURCES = bindings/cxx/classes.cpp
bindings_cxx_libsigrokxx_la_LIBADD = -lsigrok $(glibmm_LIBS)
bindings_cxx_libsigrokxx_la_LDFLAGS = $(SR_LIB_LDFLAGS)
library_include_HEADERS += \
bindings/cxx/include/libsigrok/libsigrok.hpp \
bindings/cxx/include/libsigrok/enums.hpp
pkgconfig_DATA += bindings/cxx/libsigrokxx.pc
bindings/cxx/classes.lo: bindings/cxx/enums.cpp
bindings/cxx/enums.cpp: bindings/cxx/enums.py bindings/cxx/libsigrok.xml \
bindings/cxx/ConfigKey_methods.cpp bindings/cxx/QuantityFlag_methods.cpp
python $<
bindings/cxx/libsigrok.xml: include/libsigrok/libsigrok.h
gccxml $(CFLAGS) -DGLIB_DISABLE_DEPRECATION_WARNINGS $< -fxml=$@
endif
MAINTAINERCLEANFILES = ChangeLog
.PHONY: ChangeLog

View File

@ -0,0 +1,70 @@
const DataType *ConfigKey::get_data_type() const
{
const struct sr_config_info *info = sr_config_info_get(id);
if (!info)
throw Error(SR_ERR_NA);
return DataType::get(info->datatype);
}
string ConfigKey::get_identifier() const
{
const struct sr_config_info *info = sr_config_info_get(id);
if (!info)
throw Error(SR_ERR_NA);
return valid_string(info->id);
}
string ConfigKey::get_description() const
{
const struct sr_config_info *info = sr_config_info_get(id);
if (!info)
throw Error(SR_ERR_NA);
return valid_string(info->name);
}
const ConfigKey *ConfigKey::get(string identifier)
{
const struct sr_config_info *info = sr_config_info_name_get(identifier.c_str());
if (!info)
throw Error(SR_ERR_ARG);
return get(info->key);
}
Glib::VariantBase ConfigKey::parse_string(string value) const
{
GVariant *variant;
uint64_t p, q;
switch (get_data_type()->get_id())
{
case SR_T_UINT64:
check(sr_parse_sizestring(value.c_str(), &p));
variant = g_variant_new_uint64(p);
break;
case SR_T_STRING:
variant = g_variant_new_string(value.c_str());
break;
case SR_T_BOOL:
variant = g_variant_new_boolean(sr_parse_boolstring(value.c_str()));
break;
case SR_T_FLOAT:
variant = g_variant_new_double(stod(value));
break;
case SR_T_RATIONAL_PERIOD:
check(sr_parse_period(value.c_str(), &p, &q));
variant = g_variant_new("(tt)", p, q);
break;
case SR_T_RATIONAL_VOLT:
check(sr_parse_voltage(value.c_str(), &p, &q));
variant = g_variant_new("(tt)", p, q);
break;
case SR_T_INT32:
variant = g_variant_new_int32(stoi(value));
break;
default:
throw Error(SR_ERR_BUG);
}
return Glib::VariantBase(variant, true);
}

View File

@ -0,0 +1,5 @@
const DataType *get_data_type() const;
string get_identifier() const;
string get_description() const;
static const ConfigKey *get(string identifier);
Glib::VariantBase parse_string(string value) const;

View File

@ -0,0 +1,13 @@
vector<const QuantityFlag *>
QuantityFlag::flags_from_mask(unsigned int mask)
{
auto result = vector<const QuantityFlag *>();
while (mask)
{
unsigned int new_mask = mask & (mask - 1);
result.push_back(QuantityFlag::get(
static_cast<enum sr_mqflag>(mask ^ new_mask)));
mask = new_mask;
}
return result;
}

View File

@ -0,0 +1,2 @@
static vector<const QuantityFlag *>
flags_from_mask(unsigned int mask);

1123
bindings/cxx/classes.cpp Normal file

File diff suppressed because it is too large Load Diff

142
bindings/cxx/enums.py Normal file
View File

@ -0,0 +1,142 @@
##
## This file is part of the libsigrok project.
##
## Copyright (C) 2014 Martin Ling <martin-sigrok@earth.li>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 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 General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
from pygccxml import parser, declarations
from collections import OrderedDict
import sys, os, re
# Get directory this script is in.
dirname = os.path.dirname(os.path.realpath(__file__))
# Parse GCCXML output to get declaration tree.
decls = parser.parse_xml_file(
os.path.join(dirname, "libsigrok.xml"), parser.config_t())
# Get global namespace from declaration tree.
ns = declarations.get_global_namespace(decls)
mapping = dict([
('sr_loglevel', 'LogLevel'),
('sr_packettype', 'PacketType'),
('sr_mq', 'Quantity'),
('sr_unit', 'Unit'),
('sr_mqflag', 'QuantityFlag'),
('sr_configkey', 'ConfigKey'),
('sr_datatype', 'DataType'),
('sr_channeltype', 'ChannelType'),
('sr_trigger_matches', 'TriggerMatchType')])
classes = OrderedDict()
# Build mapping between class names and enumerations.
for enum in ns.enumerations():
if enum.name in mapping:
classname = mapping[enum.name]
classes[classname] = enum
header = open(os.path.join(dirname, 'include/libsigrok/enums.hpp'), 'w')
code = open(os.path.join(dirname, 'enums.cpp'), 'w')
for file in (header, code):
print >> file, "/* Generated file - edit enums.py instead! */"
# Template for beginning of class declaration and public members.
header_public_template = """
class SR_API {classname} : public EnumValue<enum {enumname}>
{{
public:
static const {classname} *get(int id);
"""
# Template for beginning of private members.
header_private_template = """
private:
static const std::map<enum {enumname}, const {classname} *> values;
{classname}(enum {enumname} id, const char name[]);
"""
# Template for class method definitions.
code_template = """
{classname}::{classname}(enum {enumname} id, const char name[]) :
EnumValue<enum {enumname}>(id, name)
{{
}}
const {classname} *{classname}::get(int id)
{{
return {classname}::values.at(static_cast<{enumname}>(id));
}}
"""
for classname, enum in classes.items():
# Begin class and public declarations
print >> header, header_public_template.format(
classname=classname, enumname=enum.name)
# Declare public pointers for each enum value
for name, value in enum.values:
trimmed_name = re.sub("^SR_[A-Z]+_", "", name)
print >> header, '\tstatic const %s * const %s;' % (classname, trimmed_name)
# Declare additional methods if present
filename = os.path.join(dirname, "%s_methods.hpp" % classname)
if os.path.exists(filename):
print >> header, str.join('', open(filename).readlines())
# Begin private declarations
print >> header, header_private_template.format(
classname=classname, enumname=enum.name)
# Declare private constants for each enum value
for name, value in enum.values:
trimmed_name = re.sub("^SR_[A-Z]+_", "", name)
print >> header, '\tstatic const %s _%s;' % (classname, trimmed_name)
# End class declaration
print >> header, '};'
# Begin class code
print >> code, code_template.format(
classname=classname, enumname=enum.name)
# Define private constants for each enum value
for name, value in enum.values:
trimmed_name = re.sub("^SR_[A-Z]+_", "", name)
print >> code, 'const %s %s::_%s = %s(%s, "%s");' % (
classname, classname, trimmed_name, classname, name, trimmed_name)
# Define public pointers for each enum value
for name, value in enum.values:
trimmed_name = re.sub("^SR_[A-Z]+_", "", name)
print >> code, 'const %s * const %s::%s = &%s::_%s;' % (
classname, classname, trimmed_name, classname, trimmed_name)
# Define map of enum values to constants
print >> code, 'const std::map<enum %s, const %s *> %s::values = {' % (
enum.name, classname, classname)
for name, value in enum.values:
trimmed_name = re.sub("^SR_[A-Z]+_", "", name)
print >> code, '\t{%s, %s::%s},' % (name, classname, trimmed_name)
print >> code, '};'
# Define additional methods if present
filename = os.path.join(dirname, "%s_methods.cpp" % classname)
if os.path.exists(filename):
print >> code, str.join('', open(filename).readlines())

View File

@ -0,0 +1,645 @@
/*
* This file is part of the libsigrok project.
*
* Copyright (C) 2013-2014 Martin Ling <martin-sigrok@earth.li>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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 General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBSIGROK_HPP
#define LIBSIGROK_HPP
#include "libsigrok/libsigrok.h"
#include <glibmm-2.4/glibmm.h>
#include <stdexcept>
#include <memory>
#include <vector>
#include <map>
namespace sigrok
{
using namespace std;
/* Forward declarations */
class SR_API Error;
class SR_API Context;
class SR_API Driver;
class SR_API Device;
class SR_API HardwareDevice;
class SR_API Channel;
class SR_API EventSource;
class SR_API Session;
class SR_API ConfigKey;
class SR_API InputFormat;
class SR_API OutputFormat;
class SR_API LogLevel;
class SR_API ChannelGroup;
class SR_API Trigger;
class SR_API TriggerStage;
class SR_API TriggerMatch;
class SR_API TriggerMatchType;
class SR_API ChannelType;
class SR_API Packet;
class SR_API PacketPayload;
class SR_API PacketType;
class SR_API Quantity;
class SR_API Unit;
class SR_API QuantityFlag;
class SR_API InputFileDevice;
class SR_API Output;
class SR_API DataType;
/** Exception thrown when an error code is returned by any libsigrok call. */
class SR_API Error: public exception
{
public:
Error(int result);
~Error() throw();
const int result;
const char *what() const throw();
};
/** Base template for most classes which wrap a struct type from libsigrok. */
template <class Parent, typename Struct> class SR_API StructureWrapper :
public enable_shared_from_this<StructureWrapper<Parent, Struct> >
{
public:
/** Parent object which owns this child object's underlying structure.
This shared pointer will be null when this child is unused, but
will be assigned to point to the parent before any shared pointer
to this child is handed out to the user.
When the reference count of this child falls to zero, this shared
pointer to its parent is reset by a custom deleter on the child's
shared pointer.
This strategy ensures that the destructors for both the child and
the parent are called at the correct time, i.e. only when all
references to both the parent and all its children are gone. */
shared_ptr<Parent> parent;
protected:
Struct *structure;
StructureWrapper<Parent, Struct>(Struct *structure) :
structure(structure)
{
}
};
/** Type of log callback */
typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
/** Context */
class SR_API Context : public enable_shared_from_this<Context>
{
public:
/** Create new context */
static shared_ptr<Context> create();
/** libsigrok package version. */
string get_package_version();
/** libsigrok library version. */
string get_lib_version();
/** Available hardware drivers, indexed by name. */
map<string, shared_ptr<Driver> > get_drivers();
/** Available input formats, indexed by name. */
map<string, shared_ptr<InputFormat> > get_input_formats();
/** Available output formats, indexed by name. */
map<string, shared_ptr<OutputFormat> > get_output_formats();
/** Current log level. */
const LogLevel *get_log_level();
/** Set the log level. */
void set_log_level(const LogLevel *level);
/** Current log domain. */
string get_log_domain();
/** Set the log domain. */
void set_log_domain(string value);
/** Set the log callback. */
void set_log_callback(LogCallbackFunction callback);
/** Set the log callback to the default handler. */
void set_log_callback_default();
/** Create a new session. */
shared_ptr<Session> create_session();
/** Load a saved session. */
shared_ptr<Session> load_session(string filename);
/** Create a new trigger. */
shared_ptr<Trigger> create_trigger(string name);
protected:
struct sr_context *structure;
map<string, Driver *> drivers;
map<string, InputFormat *> input_formats;
map<string, OutputFormat *> output_formats;
Session *session;
LogCallbackFunction log_callback;
Context();
~Context();
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(Context *context) { delete context; }
};
friend class Deleter;
friend class Session;
friend class Driver;
};
/** Hardware driver */
class SR_API Driver : public StructureWrapper<Context, struct sr_dev_driver>
{
public:
/** Name of this driver. */
string get_name();
/** Long name for this driver. */
string get_long_name();
/** Scan for devices and return a list of devices found. */
vector<shared_ptr<HardwareDevice> > scan(
map<const ConfigKey *, Glib::VariantBase> options = {});
protected:
bool initialized;
vector<HardwareDevice *> devices;
Driver(struct sr_dev_driver *structure);
~Driver();
friend class Context;
friend class HardwareDevice;
friend class ChannelGroup;
};
/** An object that can be configured. */
class SR_API Configurable
{
public:
/** Read configuration for the given key. */
Glib::VariantBase config_get(const ConfigKey *key);
/** Set configuration for the given key to a specified value. */
void config_set(const ConfigKey *key, Glib::VariantBase value);
/** Enumerate available values for the given configuration key. */
Glib::VariantBase config_list(const ConfigKey *key);
protected:
Configurable(
struct sr_dev_driver *driver,
struct sr_dev_inst *sdi,
struct sr_channel_group *channel_group);
virtual ~Configurable();
struct sr_dev_driver *config_driver;
struct sr_dev_inst *config_sdi;
struct sr_channel_group *config_channel_group;
};
/** Generic device (may be real or from an input file) */
class SR_API Device :
public Configurable,
public StructureWrapper<Context, struct sr_dev_inst>
{
public:
/** Vendor name for this device. */
string get_vendor();
/** Model name for this device. */
string get_model();
/** Version string for this device. */
string get_version();
/** List of the channels available on this device. */
vector<shared_ptr<Channel> > get_channels();
/** Open device. */
void open();
/** Close device. */
void close();
protected:
Device(struct sr_dev_inst *structure);
~Device();
vector<Channel *> channels;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(Device *device) { delete device; }
};
friend class Deleter;
friend class Session;
friend class Channel;
friend class ChannelGroup;
friend class Output;
};
/** Hardware device (connected via a driver) */
class SR_API HardwareDevice : public Device
{
public:
/** Driver providing this device. */
shared_ptr<Driver> get_driver();
/** Channel groups available on this device, indexed by name. */
map<string, shared_ptr<ChannelGroup> > get_channel_groups();
protected:
HardwareDevice(Driver *driver, struct sr_dev_inst *structure);
~HardwareDevice();
Driver *driver;
map<string, ChannelGroup *> channel_groups;
friend class Driver;
friend class ChannelGroup;
};
/** Channel */
class SR_API Channel : public StructureWrapper<Device, struct sr_channel>
{
public:
/** Current name of this channel. */
string get_name();
/** Set the name of this channel. */
void set_name(string name);
/** Type of this channel. */
const ChannelType *get_type();
/** Enabled status of this channel. */
bool get_enabled();
/** Set the enabled status of this channel. */
void set_enabled(bool value);
protected:
Channel(struct sr_channel *structure);
~Channel();
const ChannelType * const type;
friend class Device;
friend class ChannelGroup;
friend class Session;
friend class TriggerStage;
};
/** Channel group */
class SR_API ChannelGroup :
public StructureWrapper<HardwareDevice, struct sr_channel_group>,
public Configurable
{
public:
/** Name of this channel group. */
string get_name();
/** List of the channels in this group. */
vector<shared_ptr<Channel> > get_channels();
protected:
ChannelGroup(HardwareDevice *device, struct sr_channel_group *structure);
~ChannelGroup();
vector<Channel *> channels;
friend class HardwareDevice;
};
/** Trigger */
class SR_API Trigger : public enable_shared_from_this<Trigger>
{
public:
string get_name();
vector<shared_ptr<TriggerStage> > get_stages();
shared_ptr<TriggerStage> add_stage();
protected:
Trigger(shared_ptr<Context> context, string name);
~Trigger();
struct sr_trigger *structure;
shared_ptr<Context> context;
vector<TriggerStage *> stages;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(Trigger *trigger) { delete trigger; }
};
friend class Context;
};
/** Trigger stage */
class SR_API TriggerStage : public StructureWrapper<Trigger, struct sr_trigger_stage>
{
public:
int get_number();
vector<shared_ptr<TriggerMatch> > get_matches();
void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type);
void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
protected:
vector<TriggerMatch *> matches;
TriggerStage(struct sr_trigger_stage *structure);
~TriggerStage();
friend class Trigger;
};
/** Trigger match */
class SR_API TriggerMatch : public StructureWrapper<TriggerStage, struct sr_trigger_match>
{
public:
shared_ptr<Channel> get_channel();
const TriggerMatchType *get_type();
float get_value();
protected:
TriggerMatch(struct sr_trigger_match *structure, shared_ptr<Channel> channel);
~TriggerMatch();
shared_ptr<Channel> channel;
friend class TriggerStage;
};
/** Type of datafeed callback */
typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
DatafeedCallbackFunction;
/** Data required for C callback function to call a C++ datafeed callback */
class SR_PRIV DatafeedCallbackData
{
public:
void run(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *pkt);
protected:
DatafeedCallbackFunction callback;
DatafeedCallbackData(Session *session,
DatafeedCallbackFunction callback);
Session *session;
friend class Session;
};
/** Type of source callback */
typedef function<bool(Glib::IOCondition)>
SourceCallbackFunction;
/** Data required for C callback function to call a C++ source callback */
class SR_PRIV SourceCallbackData
{
public:
bool run(int revents);
protected:
SourceCallbackData(shared_ptr<EventSource> source);
shared_ptr<EventSource> source;
friend class Session;
};
/** Event source. */
class SR_API EventSource
{
public:
/** Create an event source from a file descriptor. */
static shared_ptr<EventSource> create(int fd, Glib::IOCondition events,
int timeout, SourceCallbackFunction callback);
/** Create an event source from a Glib::PollFD */
static shared_ptr<EventSource> create(Glib::PollFD pollfd, int timeout,
SourceCallbackFunction callback);
/** Create an event source from a Glib::IOChannel */
static shared_ptr<EventSource> create(
Glib::RefPtr<Glib::IOChannel> channel, Glib::IOCondition events,
int timeout, SourceCallbackFunction callback);
protected:
EventSource(int timeout, SourceCallbackFunction callback);
~EventSource();
enum source_type {
SOURCE_FD,
SOURCE_POLLFD,
SOURCE_IOCHANNEL
} type;
int fd;
Glib::PollFD pollfd;
Glib::RefPtr<Glib::IOChannel> channel;
Glib::IOCondition events;
int timeout;
SourceCallbackFunction callback;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(EventSource *source) { delete source; }
};
friend class Deleter;
friend class Session;
friend class SourceCallbackData;
};
/** Session */
class SR_API Session
{
public:
/** Add a device to this session. */
void add_device(shared_ptr<Device> device);
/** List devices attached to this session. */
vector<shared_ptr<Device> > get_devices();
/** Remove all devices from this session. */
void remove_devices();
/** Add a datafeed callback to this session. */
void add_datafeed_callback(DatafeedCallbackFunction callback);
/** Remove all datafeed callbacks from this session. */
void remove_datafeed_callbacks();
/** Add an event source. */
void add_source(shared_ptr<EventSource> source);
/** Remove an event source. */
void remove_source(shared_ptr<EventSource> source);
/** Start the session. */
void start();
/** Run the session event loop. */
void run();
/** Stop the session. */
void stop();
/** Begin saving session to a file. */
void begin_save(string filename);
/** Append a packet to the session file being saved. */
void append(shared_ptr<Device> device, shared_ptr<Packet> packet);
protected:
Session(shared_ptr<Context> context);
Session(shared_ptr<Context> context, string filename);
~Session();
struct sr_session *structure;
const shared_ptr<Context> context;
map<const struct sr_dev_inst *, shared_ptr<Device> > devices;
vector<DatafeedCallbackData *> datafeed_callbacks;
map<shared_ptr<EventSource>, SourceCallbackData *> source_callbacks;
bool saving;
bool save_initialized;
string save_filename;
uint64_t save_samplerate;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(Session *session) { delete session; }
};
friend class Deleter;
friend class Context;
friend class DatafeedCallbackData;
};
/** Datafeed packet */
class SR_API Packet
{
public:
/** Payload of this packet. */
PacketPayload *get_payload();
protected:
Packet(const struct sr_datafeed_packet *structure);
~Packet();
const struct sr_datafeed_packet *structure;
PacketPayload *payload;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(Packet *packet) { delete packet; }
};
friend class Deleter;
friend class Session;
friend class Output;
friend class DatafeedCallbackData;
};
/** Abstract base class for datafeed packet payloads. */
class SR_API PacketPayload
{
protected:
PacketPayload();
virtual ~PacketPayload() = 0;
virtual void *get_data() = 0;
virtual size_t get_data_size() = 0;
friend class Packet;
friend class Output;
};
/** Logic data payload */
class SR_API Logic : public PacketPayload
{
protected:
Logic(const struct sr_datafeed_logic *structure);
~Logic();
const struct sr_datafeed_logic *structure;
vector<uint8_t> data;
void *get_data();
size_t get_data_size();
friend class Packet;
};
/** Analog data payload */
class SR_API Analog : public PacketPayload
{
public:
/** Number of samples in this packet. */
unsigned int get_num_samples();
/** Measured quantity of the samples in this packet. */
const Quantity *get_mq();
/** Unit of the samples in this packet. */
const Unit *get_unit();
/** Measurement flags associated with the samples in this packet. */
vector<const QuantityFlag *> get_mq_flags();
protected:
Analog(const struct sr_datafeed_analog *structure);
~Analog();
const struct sr_datafeed_analog *structure;
void *get_data();
size_t get_data_size();
friend class Packet;
};
/** Input format */
class SR_API InputFormat :
public StructureWrapper<Context, struct sr_input_format>
{
public:
/** Name of this input format. */
string get_name();
/** Description of this input format. */
string get_description();
/** Check whether a given file matches this input format. */
bool format_match(string filename);
/** Open a file using this input format. */
shared_ptr<InputFileDevice> open_file(string filename,
map<string, string> options = {});
protected:
InputFormat(struct sr_input_format *structure);
~InputFormat();
friend class Context;
friend class InputFileDevice;
};
/** Virtual device associated with an input file */
class SR_API InputFileDevice : public Device
{
public:
/** Load data from file. */
void load();
protected:
InputFileDevice(shared_ptr<InputFormat> format,
struct sr_input *input, string filename);
~InputFileDevice();
struct sr_input *input;
shared_ptr<InputFormat> format;
string filename;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(InputFileDevice *device) { delete device; }
};
friend class Deleter;
friend class InputFormat;
};
/** Output format */
class SR_API OutputFormat :
public StructureWrapper<Context, struct sr_output_format>
{
public:
/** Name of this output format. */
string get_name();
/** Description of this output format. */
string get_description();
/** Create an output using this format. */
shared_ptr<Output> create_output(shared_ptr<Device> device, map<string, string> options = {});
protected:
OutputFormat(struct sr_output_format *structure);
~OutputFormat();
friend class Context;
friend class Output;
};
/** Output instance (an output format applied to a device) */
class SR_API Output
{
public:
/** Update output with data from the given packet. */
string receive(shared_ptr<Packet> packet);
protected:
Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
Output(shared_ptr<OutputFormat> format,
shared_ptr<Device> device, map<string, string> options);
~Output();
struct sr_output *structure;
const shared_ptr<OutputFormat> format;
const shared_ptr<Device> device;
const map<string, string> options;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(Output *output) { delete output; }
};
friend class Deleter;
friend class OutputFormat;
};
/** Base class for objects which wrap an enumeration value from libsigrok */
template <typename T> class SR_API EnumValue
{
public:
/** The enum constant associated with this value. */
T get_id() const { return id; }
/** The name associated with this value. */
string get_name() const { return name; }
protected:
EnumValue(T id, const char name[]) : id(id), name(name) {}
~EnumValue() {}
const T id;
const string name;
};
#include "enums.hpp"
}
#endif // LIBSIGROK_HPP

View File

@ -0,0 +1,15 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libsigrokxx
Description: C++ bindings for libsigrok
URL: http://www.sigrok.org
Requires: libsigrok glibmm-2.4
Requires.private: @SR_PKGLIBS@
Version: @VERSION@
Libs: -L${libdir} -lsigrokxx
Libs.private: -lm
Cflags: -I${includedir}

View File

@ -46,10 +46,12 @@ AH_BOTTOM([#endif /* SR_CONFIG_H */])
# and enforce use of SR_API to explicitly mark all public API functions.
COMMON_FLAGS="$CFLAGS -Wall -Wextra -fvisibility=hidden"
CFLAGS="$COMMON_FLAGS -Wmissing-prototypes"
CXXFLAGS="-std=c++11 $COMMON_FLAGS"
# Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LN_S
@ -152,6 +154,21 @@ AC_ARG_ENABLE(libusb,
AC_HELP_STRING([--disable-libusb],
[disable libusb support [default=detect]]))
# Language binding '--enable' options
AC_ARG_ENABLE(c++,
AC_HELP_STRING([--enable-cxx],
[build C++ bindings [default=yes]]),
[BINDINGS_CXX="$enableval"], [BINDINGS_CXX="yes"])
# Check if the C++ compiler supports the C++11 standard.
AX_CXX_COMPILE_STDCXX_11(,[optional])
if test "x$HAVE_CXX11" != "x1"; then
BINDINGS_CXX="no"
fi
# Checks for libraries.
case "$host" in
@ -301,6 +318,11 @@ if test "x$have_libftdi" = "xno"; then
HW_ASIX_SIGMA="no"; HW_CHRONOVU_LA="no"; HW_IKALOGIC_SCANAPLUS="no";
fi
# glibmm-2.4 is needed for the C++ bindings.
PKG_CHECK_MODULES([glibmm], [glibmm-2.4 >= 2.32.0],
[CXXFLAGS="$CXXFLAGS $glibmm_CFLAGS";
CXXLIBS="$CXXLIBS $glibmm_LIBS"], [BINDINGS_CXX="no"])
# The Check unit testing framework is optional. Disable if not found.
PKG_CHECK_MODULES([check], [check >= 0.9.4],
[have_check="yes"], [have_check="no"])
@ -317,6 +339,7 @@ esac
AC_SUBST(SR_PKGLIBS)
CFLAGS="$CFLAGS -I./include/libsigrok $LIB_CFLAGS"
CXXFLAGS="$CXXFLAGS -I./include -I./bindings/cxx/include $LIB_CFLAGS"
# Now set AM_CONDITIONALs and AC_DEFINEs for the enabled/disabled drivers.
@ -505,6 +528,8 @@ if test "x$HW_ZEROPLUS_LOGIC_CUBE" = "xyes"; then
AC_DEFINE(HAVE_HW_ZEROPLUS_LOGIC_CUBE, 1, [ZEROPLUS Logic Cube support])
fi
AM_CONDITIONAL(BINDINGS_CXX, test x$BINDINGS_CXX = xyes)
# Checks for header files.
# These are already checked: inttypes.h stdint.h stdlib.h string.h unistd.h.
@ -525,7 +550,8 @@ AC_SUBST(SR_PACKAGE_VERSION_MINOR)
AC_SUBST(SR_PACKAGE_VERSION_MICRO)
AC_SUBST(SR_PACKAGE_VERSION)
AC_CONFIG_FILES([Makefile include/libsigrok/version.h libsigrok.pc])
AC_CONFIG_FILES([Makefile include/libsigrok/version.h libsigrok.pc
bindings/cxx/libsigrokxx.pc])
AC_OUTPUT
@ -557,3 +583,6 @@ done
echo -e "\nEnabled hardware drivers:\n${driver_summary}"
echo -e "\nEnabled language bindings:\n"
echo " - C++............................. $BINDINGS_CXX"
echo