SWIG: test callback & output grabbing

This commit is contained in:
Philippe Teuwen
2020-12-17 00:31:42 +01:00
parent c7e5648164
commit 39710c5fdf
26 changed files with 8332 additions and 6950 deletions
+22 -19
View File
@@ -289,11 +289,11 @@ endif
# SWIG #
########
ifneq ("$(wildcard src/pm3_luawrap.c)","")
ifneq ("$(wildcard src/pm3_luawrap.cpp)","")
SWIG_LUA_FOUND = 1
endif
ifeq ($(PYTHON_FOUND),1)
ifneq ("$(wildcard src/pm3_pywrap.c)","")
ifneq ("$(wildcard src/pm3_pywrap.cpp)","")
SWIG_PYTHON_FOUND = 1
endif
endif
@@ -305,6 +305,10 @@ PM3CFLAGS = $(CFLAGS)
PM3CFLAGS += -I./src -I./include -I../include -I../common -I../common_fpga $(INCLUDES)
# WIP Testing
#PM3CFLAGS += -std=c11 -pedantic
CXXFLAGS ?= -Wall -Werror -O3
PM3CXXFLAGS = $(CXXFLAGS)
PM3CXXFLAGS += -I../include -I./include -I../common $(INCLUDES)
PREFIX ?= /usr/local
ifneq (,$(findstring MINGW,$(platform)))
@@ -330,15 +334,13 @@ endif
ifeq ($(SWIG_LUA_FOUND),1)
PM3CFLAGS += -DHAVE_LUA_SWIG
PM3CXXFLAGS += -DHAVE_LUA_SWIG
endif
ifeq ($(SWIG_PYTHON_FOUND),1)
PM3CFLAGS += -DHAVE_PYTHON_SWIG
PM3CXXFLAGS += -DHAVE_PYTHON_SWIG
endif
CXXFLAGS ?= -Wall -Werror -O3
PM3CXXFLAGS = $(CXXFLAGS)
PM3CXXFLAGS += -I../include -I./include
ifeq ($(QT_FOUND),1)
PM3CFLAGS += -DHAVE_GUI
PM3CXXFLAGS += -DQT_NO_DEBUG
@@ -568,7 +570,6 @@ SRCS = aiddesfire.c \
mifare/mifaredefault.c \
mifare/mifarehost.c \
mifare/ndef.c \
pm3.c \
pm3_binlib.c \
pm3_bitlib.c \
preferences.c \
@@ -605,10 +606,10 @@ SRCS += bucketsort.c \
SWIGSRCS =
ifeq ($(SWIG_LUA_FOUND),1)
SWIGSRCS += pm3_luawrap.c
SWIGSRCS += pm3_luawrap.cpp
endif
ifeq ($(SWIG_PYTHON_FOUND),1)
SWIGSRCS += pm3_pywrap.c
SWIGSRCS += pm3_pywrap.cpp
endif
# gui
@@ -617,6 +618,7 @@ ifeq ($(QT_FOUND),1)
else
CXXSRCS = guidummy.cpp
endif
CXXSRCS += pm3.cpp
# OS X
ifeq ($(platform),Darwin)
@@ -624,7 +626,7 @@ ifeq ($(platform),Darwin)
endif
OBJS = $(SRCS:%.c=$(OBJDIR)/%.o)
OBJS += $(SWIGSRCS:%.c=$(OBJDIR)/%.o)
OBJS += $(SWIGSRCS:%.cpp=$(OBJDIR)/%.o)
OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o)
OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
@@ -756,13 +758,13 @@ endif
# SWIG #
########
src/pm3_luawrap.c: pm3.i
src/pm3_luawrap.cpp: pm3.i
$(info [=] GEN $@)
$(Q)$(SWIG) -lua -o $@ $<
$(Q)$(SWIG) -c++ -lua -o $@ $<
src/pm3_pywrap.c: pm3.i
src/pm3_pywrap.cpp: pm3.i
$(info [=] GEN $@)
$(Q)$(SWIG) -python -o $@ $<
$(Q)$(SWIG) -c++ -python -o $@ $<
########
# misc #
@@ -779,11 +781,12 @@ src/version.c: default_version.c
print-%: ; @echo $* = $($*)
# SWIG files emit a number of warnings, we've to ignore them
%wrap.o: %wrap.c
$(OBJDIR)/%wrap.o : %wrap.c $(OBJDIR)/%.d
$(info [-] CC $<)
%wrap.o: %wrap.cpp
$(OBJDIR)/%wrap.o : %wrap.cpp $(OBJDIR)/%.d
$(info [-] CXX $<)
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -Wno-missing-prototypes -Wno-missing-declarations -Wno-missing-field-initializers -c -o $@ $<
# $(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) -Wno-missing-prototypes -Wno-missing-declarations -Wno-missing-field-initializers -c -o $@ $<
$(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) -c -o $@ $<
$(Q)$(POSTCOMPILE)
%.o: %.c
@@ -808,7 +811,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
$(Q)$(POSTCOMPILE)
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \
$(patsubst %wrap.c, $(OBJDIR)/%.d, $(SWIGSRCS)) \
$(patsubst %wrap.cpp, $(OBJDIR)/%.d, $(SWIGSRCS)) \
$(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS))
@@ -1,5 +1,5 @@
#!/bin/bash
cd ..
make src/pm3_luawrap.c
make src/pm3_pywrap.c
make src/pm3_luawrap.cpp
make src/pm3_pywrap.cpp
@@ -0,0 +1,5 @@
#!/bin/bash
../../pm3 -c "script run testembedded_cb.py"
# cf https://github.com/swig/swig/tree/master/Examples/python/callback
# cf https://rawgit.com/swig/swig/master/Doc/Manual/SWIGPlus.html#SWIGPlus_target_language_callbacks
@@ -0,0 +1,2 @@
http://www.swig.org/Doc4.0/SWIG.html#SWIG_nn30
http://www.swig.org/Doc4.0/SWIGPlus.html#SWIGPlus_target_language_callbacks
@@ -0,0 +1,4 @@
/* File : example.cxx */
#include "example.h"
@@ -0,0 +1,22 @@
/* File : example.h */
#include <iostream>
class Callback {
public:
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
virtual void run() { std::cout << "Callback::run()" << std::endl; }
};
class Caller {
private:
Callback *_callback;
public:
Caller(): _callback(0) {}
~Caller() { delCallback(); }
void delCallback() { delete _callback; _callback = 0; }
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
void call() { if (_callback) _callback->run(); }
};
@@ -0,0 +1,11 @@
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}
/* turn on director wrapping Callback */
%feature("director") Callback;
%include "example.h"
@@ -0,0 +1,57 @@
# file: runme.py
# This file illustrates the cross language polymorphism using directors.
import example
class PyCallback(example.Callback):
def __init__(self):
example.Callback.__init__(self)
def run(self):
print("PyCallback.run()")
# Create an Caller instance
caller = example.Caller()
# Add a simple C++ callback (caller owns the callback, so
# we disown it first by clearing the .thisown flag).
print("Adding and calling a normal C++ callback")
print("----------------------------------------")
callback = example.Callback()
callback.thisown = 0
caller.setCallback(callback)
caller.call()
caller.delCallback()
print("")
print("Adding and calling a Python callback")
print("------------------------------------")
# Add a Python callback (caller owns the callback, so we
# disown it first by calling __disown__).
caller.setCallback(PyCallback().__disown__())
caller.call()
caller.delCallback()
print("")
print("Adding and calling another Python callback")
print("------------------------------------------")
# Let's do the same but use the weak reference this time.
callback = PyCallback().__disown__()
caller.setCallback(callback)
caller.call()
caller.delCallback()
# All done.
print("")
print("python exit")
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
import pm3
p=pm3.pm3()
# PyConsoleHandler class is defined and derived from C++ class ConsoleHandler
class PyConsoleHandler(pm3.ConsoleHandler):
def __init__(self):
pm3.ConsoleHandler.__init__(self)
def handle_output(self, c):
print("PY>>", c, end='')
# don't let original print routine pursuing:
return 0
#p.console("hw status")
handler = PyConsoleHandler()
result = p.console_async_wrapper("hw status", handler)
print(result)
print("Device:", p.name)
+2 -2
View File
@@ -1,5 +1,5 @@
#!/bin/bash
cd ..
make src/pm3_luawrap.c
make src/pm3_pywrap.c
make src/pm3_luawrap.cpp
make src/pm3_pywrap.cpp
+15
View File
@@ -1,11 +1,26 @@
#ifndef LIBPM3_H
#define LIBPM3_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct pm3_device pm3;
pm3 *pm3_open(char *port);
// not catching output
int pm3_console(pm3 *dev, char *cmd);
// catching output as it comes
int pm3_console_async(pm3 *dev, char *cmd, int (*callback)(char* s));
// catching output at the end
//int pm3_console_sync(pm3 *dev, char *cmd, char* outbuf, int outbufsize);
const char *pm3_name_get(pm3 *dev);
void pm3_close(pm3 *dev);
pm3 *pm3_get_current_dev(void);
#ifdef __cplusplus
}
#endif
#endif // LIBPM3_H
+8
View File
@@ -0,0 +1,8 @@
#ifndef LIBPM3PP_H
#define LIBPM3PP_H
#include "pm3.h"
#include "pm3_helper.hpp"
int pm3_console_async_wrapper(pm3 *dev, char *cmd, ConsoleHandler *console_handler);
#endif // LIBPM3PP_H
+10
View File
@@ -0,0 +1,10 @@
#ifndef LIBPM3HELPERPP_H
#define LIBPM3HELPERPP_H
class ConsoleHandler {
public:
virtual int handle_output(char *string) = 0;
virtual ~ConsoleHandler() {}
};
#endif // LIBPM3HELPERPP_H
+7
View File
@@ -322,6 +322,13 @@ int CommandReceived(char *Cmd) {
return CmdsParse(CommandTable, Cmd);
}
int CommandReceivedCB(char *Cmd, print_cb_t callback) {
g_printCallback = callback;
int res = CmdsParse(CommandTable, Cmd);
g_printCallback = NULL;
return res;
}
command_t *getTopLevelCommandTable(void) {
return CommandTable;
}
+9
View File
@@ -13,9 +13,18 @@
#include "common.h"
#include "cmdparser.h" // command_t
#include "util.h" // print_cb_t
#ifdef __cplusplus
extern "C" {
#endif
int CommandReceived(char *Cmd);
int CmdRem(const char *Cmd);
command_t *getTopLevelCommandTable(void);
int CommandReceivedCB(char *Cmd, print_cb_t callback);
#ifdef __cplusplus
}
#endif
#endif
+18 -1
View File
@@ -2,7 +2,7 @@
// User API
//-----------------------------------------------------------------------------
#include "pm3.h"
#include "pm3.hpp"
#include <stdlib.h>
@@ -46,6 +46,23 @@ int pm3_console(pm3_device *dev, char *Cmd) {
return CommandReceived(Cmd);
}
static ConsoleHandler *console_handler_ptr = NULL;
static int console_handler_helper(char *string) {
return console_handler_ptr->handle_output(string);
}
int pm3_console_async_wrapper(pm3_device *dev, char *Cmd, ConsoleHandler *console_handler) {
console_handler_ptr = console_handler;
int result = pm3_console_async(dev, Cmd, &console_handler_helper);
console_handler = NULL; // ?? console_handler_ptr = NULL cf http://www.swig.org/Doc4.0/SWIGPlus.html#SWIGPlus_target_language_callbacks
return result;
}
int pm3_console_async(pm3_device *dev, char *Cmd, int (*callback)(char*)) {
// For now, there is no real device context:
(void) dev;
return CommandReceivedCB(Cmd, callback);
}
const char *pm3_name_get(pm3_device *dev) {
return dev->conn->serial_port_name;
}
+8 -2
View File
@@ -1,7 +1,7 @@
%module pm3
%module(directors="1") pm3
%{
/* Include the header in the wrapper code */
#include "pm3.h"
#include "pm3.hpp"
#include "comms.h"
%}
@@ -31,9 +31,15 @@ typedef struct {
}
}
int console(char *cmd);
//int console_async(char *cmd, int (*callback)(char*));
int console_async_wrapper(char *cmd, ConsoleHandler *handler);
char const * const name;
}
} pm3;
//%nodefaultctor device;
//%nodefaultdtor device;
/* Parse the header file to generate wrappers */
%feature("director") ConsoleHandler;
%include "../include/pm3_helper.hpp"
+27
View File
@@ -61,6 +61,8 @@ class _SwigNonDynamicMeta(type):
__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)
import weakref
class pm3(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr
@@ -71,10 +73,35 @@ class pm3(object):
def console(self, cmd):
return _pm3.pm3_console(self, cmd)
def console_async_wrapper(self, cmd, handler):
return _pm3.pm3_console_async_wrapper(self, cmd, handler)
name = property(_pm3.pm3_name_get)
# Register pm3 in _pm3:
_pm3.pm3_swigregister(pm3)
class ConsoleHandler(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr
def handle_output(self, string):
return _pm3.ConsoleHandler_handle_output(self, string)
__swig_destroy__ = _pm3.delete_ConsoleHandler
def __init__(self):
if self.__class__ == ConsoleHandler:
_self = None
else:
_self = self
_pm3.ConsoleHandler_swiginit(self, _pm3.new_ConsoleHandler(_self, ))
def __disown__(self):
self.this.disown()
_pm3.disown_ConsoleHandler(self)
return weakref.proxy(self)
# Register ConsoleHandler in _pm3:
_pm3.ConsoleHandler_swigregister(ConsoleHandler)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More