Browse Source

修复串口BUG

disinfection_machine
zhaohe 2 years ago
parent
commit
217a1d97ab
  1. 19
      core/components/modbus/modbus.cpp
  2. 2
      core/components/modbus/modbus.hpp
  3. 1
      core/components/stringutils.hpp
  4. 248
      core/components/uart/uart.cpp
  5. 65
      core/components/uart/uart.hpp
  6. 110
      core/zexception/zexception.cpp
  7. 57
      core/zexception/zexception.hpp

19
core/components/modbus/modbus.cpp

@ -1,4 +1,5 @@
#include "modbus.hpp" #include "modbus.hpp"
#include "iflytopcpp/core/components/stringutils.hpp"
extern "C" { extern "C" {
#include "zmodbus_common.h" #include "zmodbus_common.h"
@ -44,13 +45,13 @@ ModbusMaster::ModbusMaster() {}
ModbusMaster::~ModbusMaster() {} ModbusMaster::~ModbusMaster() {}
bool ModbusMaster::initializeTtyChannel(const char* ttypath, int rate) { bool ModbusMaster::initializeTtyChannel(const char* ttypath, int rate) {
logger->info("initializeTtyChannel: ttypath: {}, rate: {}", ttypath, rate); logger->info("initializeTtyChannel: ttypath: {}, rate: {}", ttypath, rate);
uartdev = make_shared<Uart>(ttypath, rate);
int ret = uartdev->start(0);
if (ret == UART_SUCCESS) {
uartdev = make_shared<Uart>();
int ret = uartdev->open(ttypath, fmt::format("{}", rate));
if (ret == 0) {
initializedSuccess = true; initializedSuccess = true;
return true; return true;
} else { } else {
logger->error("initializeTtyChannel: uartdev->start failed, ret: {}", ret);
logger->error("initializeTtyChannel: uartdev->start failed, ret: {},{}", ret, uartdev->get_error());
return false; return false;
} }
} }
@ -83,8 +84,9 @@ int ModbusMaster::modbus03(uint8_t deviceid, uint16_t startreg, uint16_t regnum,
ret = uartdev->send((char*)txbuf, sendlength); ret = uartdev->send((char*)txbuf, sendlength);
if (ret < sendlength) { if (ret < sendlength) {
logger->error("modbus03-(d {},reg {}:{})::send packet fail", deviceid, startreg, regnum); logger->error("modbus03-(d {},reg {}:{})::send packet fail", deviceid, startreg, regnum);
return -1;
return -2;
} }
// sleep(1);
// 接收指定包长的包 // 接收指定包长的包
// add(1)+function_code(1)+num(1)+regs(2*6)+crc(2) // add(1)+function_code(1)+num(1)+regs(2*6)+crc(2)
// 1+1+1+12+2 // 1+1+1+12+2
@ -93,7 +95,7 @@ int ModbusMaster::modbus03(uint8_t deviceid, uint16_t startreg, uint16_t regnum,
ret = uartdev->receive((char*)rx.rx.data(), rxsize, overtime); ret = uartdev->receive((char*)rx.rx.data(), rxsize, overtime);
if (ret != rxsize) { if (ret != rxsize) {
logger->error("modbus03-(d {},reg {}:{})::receive_packet_safe fail", deviceid, startreg, regnum); logger->error("modbus03-(d {},reg {}:{})::receive_packet_safe fail", deviceid, startreg, regnum);
return -1;
return -3;
} }
if (((uint8_t*)rx.rx.data())[1] == uint8_t(0x90)) { if (((uint8_t*)rx.rx.data())[1] == uint8_t(0x90)) {
// receive error code // receive error code
@ -104,8 +106,9 @@ int ModbusMaster::modbus03(uint8_t deviceid, uint16_t startreg, uint16_t regnum,
} }
uint16_t crc = ZGenerateCRC16CheckCode((uint8_t*)rx.rx.data(), rxsize - 2); uint16_t crc = ZGenerateCRC16CheckCode((uint8_t*)rx.rx.data(), rxsize - 2);
if (crc != (rx.rx[rxsize - 2] << 8 | rx.rx[rxsize - 1])) { if (crc != (rx.rx[rxsize - 2] << 8 | rx.rx[rxsize - 1])) {
logger->error("modbus03-(d {},reg {}:{})::crc check fail", deviceid, startreg, regnum);
return false;
logger->error("modbus03-(d {},reg {}:{})::crc check fail,{}", deviceid, startreg, regnum,
StringUtils().bytesToString(rx.rx.data(), (size_t)rxsize));
return -4;
} }
return 0; return 0;

2
core/components/modbus/modbus.hpp

@ -30,7 +30,7 @@ class Modbus03Rx {
uint8_t deviceid; uint8_t deviceid;
uint16_t startreg; uint16_t startreg;
uint16_t regnum; uint16_t regnum;
vector<uint16_t> rx;
vector<uint8_t> rx;
public: public:
uint16_t getReg(int regoff) { uint16_t getReg(int regoff) {

1
core/components/stringutils.hpp

@ -17,6 +17,7 @@ class StringUtils {
string upper(const string& value); string upper(const string& value);
string lower(const string& value); string lower(const string& value);
string bytesToString(const uint8_t* data, size_t size); string bytesToString(const uint8_t* data, size_t size);
string bytesToString(const char* data, size_t size) { return bytesToString((const uint8_t*)data, size); }
string bytesToString(const vector<uint8_t>& byteTable) { return bytesToString(byteTable.data(), byteTable.size()); } string bytesToString(const vector<uint8_t>& byteTable) { return bytesToString(byteTable.data(), byteTable.size()); }
/** /**

248
core/components/uart/uart.cpp

@ -23,43 +23,39 @@
using namespace iflytop; using namespace iflytop;
using namespace iflytop::core; using namespace iflytop::core;
int uartStart(struct UartDevice *dev, unsigned char canonic);
int uartSend(struct UartDevice *dev, char *data, int size);
int uartReceive(struct UartDevice *dev, char *data, int size_max);
int uartStop(struct UartDevice *dev);
/*
Parameters:
struct UartDevice* dev - pointer to the UartDevice struct
unsigned char canonic - communication mode
1 - canonic communication (chars are only received after \n is detected).
0 - non canonic communication (chars are received as they arrive over UART).
Return value:
UART_FAILURE -1 failure
UART_SUCCESS 0 success
Description:
Initializes the UART device.
When calling the function, the device name (usually "/dev/ttyUL1") must be filled in dev->name and the baud rate
must be filled in dev->rate. The canonic function parameter indicates communication mode (canonic or not). In the
canonic communication mode, the received chars can be retrieved by read only after \n is detected. In the non canonic
communication mode, the received chars can be retrieved by read as they are received, as the non canonic mode is
configured with no wait.
*/
int uartStart(struct UartDevice *dev, unsigned char canonic) {
struct termios *tty;
int fd;
static map<string, uint32_t> s_baundmap = {
{"0", 0000000}, {"50", 0000001}, {"75", 0000002}, {"110", 0000003}, //
{"134", 0000004}, {"150", 0000005}, {"200", 0000006}, {"300", 0000007}, //
{"600", 0000010}, {"1200", 0000011}, {"1800", 0000012}, {"2400", 0000013}, //
{"4800", 0000014}, {"9600", 0000015}, {"19200", 0000016}, {"38400", 0000017}, //
{"57600", 0010001}, {"115200", 0010002}, {"230400", 0010003}, {"460800", 0010004}, //
{"500000", 0010005}, {"576000", 0010006}, {"921600", 0010007}, {"1000000", 0010010}, //
{"1152000", 0010011}, {"1500000", 0010012}, {"2000000", 0010013}, {"2500000", 0010014}, //
{"3000000", 0010015}, {"3500000", 0010016}, {"4000000", 0010017},
};
Uart::Uart() {}
Uart::~Uart() {}
int Uart::open(string path, string ratestr) {
int rc; int rc;
fd = open(dev->name, O_RDWR | O_NOCTTY);
if (fd < 0) {
printf("%s: failed to open file descriptor for file %s\r\n", __func__, dev->name);
return UART_FAILURE;
m_name = path;
uint32_t rate = 0;
m_fd = ::open(path.c_str(), O_RDWR | O_NOCTTY);
if (m_fd < 0) {
m_error = fmt::format("open {} failed,{}", path, strerror(errno));
return -1;
} }
tty = (struct termios *)calloc(1, sizeof(*dev->tty));
if (!tty) {
printf("%s: failed to allocate tty instance\r\n", __func__);
return UART_FAILURE;
if (s_baundmap.find(ratestr) == s_baundmap.end()) {
m_error = fmt::format("baund {} not support", ratestr);
return -1;
} }
rate = s_baundmap[ratestr];
m_rate = ratestr;
memset(&m_tty, 0, sizeof(m_tty));
// memset(tty, 0, sizeof(struct termios)); // memset(tty, 0, sizeof(struct termios));
/* /*
BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed. BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
@ -70,177 +66,66 @@ int uartStart(struct UartDevice *dev, unsigned char canonic) {
CREAD : enable receiving characters CREAD : enable receiving characters
*/ */
// tty->c_cflag = dev->rate | CRTSCTS | CS8 | CLOCAL | CREAD; // tty->c_cflag = dev->rate | CRTSCTS | CS8 | CLOCAL | CREAD;
tty->c_cflag = dev->rate | CS8 | CLOCAL | CREAD;
if (canonic) {
// canonic
/*
IGNPAR : ignore bytes with parity errors
ICRNL : map CR to NL (otherwise a CR input on the other computer
will not terminate input)
otherwise make device raw (no other input processing)
*/
tty->c_iflag = IGNPAR | ICRNL;
/*
ICANON : enable canonical input
disable all echo functionality, and don't send signals to calling program
*/
tty->c_lflag = ICANON;
} else {
m_tty.c_cflag = rate | CS8 | CLOCAL | CREAD;
// not canonic // not canonic
/* /*
IGNPAR : ignore bytes with parity errorsc_cc[VTIME] IGNPAR : ignore bytes with parity errorsc_cc[VTIME]
*/ */
tty->c_iflag = IGNPAR;
m_tty.c_iflag = IGNPAR;
/* set input mode (non-canonical, no echo,...) */ /* set input mode (non-canonical, no echo,...) */
tty->c_lflag = 0;
m_tty.c_lflag = 0;
/* Do not wait for data */ /* Do not wait for data */
tty->c_cc[VTIME] = 0; /* inter-character timer unused */
tty->c_cc[VMIN] = 0; /* blocking read until 5 chars received */
}
m_tty.c_cc[VTIME] = 10; /* inter-character timer unused */
m_tty.c_cc[VMIN] = 0; /* blocking read until 5 chars received */
/* /*
Raw output. Raw output.
*/ */
tty->c_oflag = 0;
m_tty.c_oflag = 0;
/* Flush port */ /* Flush port */
tcflush(fd, TCIFLUSH);
tcflush(m_fd, TCIFLUSH);
/* Apply attributes */ /* Apply attributes */
rc = tcsetattr(fd, TCSANOW, tty);
rc = tcsetattr(m_fd, TCSANOW, &m_tty);
if (rc) { if (rc) {
printf("%s: failed to set TCSANOW attr\r\n", __func__);
return UART_FAILURE;
m_error = fmt::format("tcsetattr {} failed,{}", path, strerror(errno));
return -1;
} }
dev->fd = fd;
dev->tty = tty;
return UART_SUCCESS;
return 0;
} }
/*
Parameters:
struct UartDevice* dev - pointer to the UartDevice struct
char *data - pointer to the array of chars to be sent over UART
int size
positive value - number of chars to be sent over UART
-1 - indicates that all the chars until string terminator \0 will be sent
Return value:
number of chars sent over UART
Description:
This function sends a number of chars over UART.
If the size function parameter is -1 then all the characters until string terminator \0 will be sent.
*/
int uartSend(struct UartDevice *dev, char *data, int size) {
int Uart::send(char *data, int size) {
if (logger->level() <= level::debug) {
logger->debug("{} send: {}", m_name, StringUtils().bytesToString((const uint8_t *)data, size));
}
int sent = 0; int sent = 0;
if (size == -1) {
size = strlen(data);
sent = write(m_fd, data, size);
if (sent < 0) {
m_error = fmt::format("write {} failed,{}", m_name, strerror(errno));
} }
sent = write(dev->fd, data, size);
#ifdef DEBUG
printf("%s: sent %d characters\r\n", __func__, sent);
#endif
return sent; return sent;
} }
/*
Parameters:
struct UartDevice* dev - pointer to the UartDevice struct
char *data - pointer to the array of chars to hold the cars revceived over UART
int size_max - the maximum number of characters to be received
Return value:
number of chars received over UART
Description:
This function receives characters over UART.
In the canonic communication mode, the received chars will be retrieved by read only after \n is detected.
In the non canonic communication mode, the received chars will be retrieved by read as they are received, as the
non canonic mode is configured with no wait.
*/
int uartReceive(struct UartDevice *dev, char *data, int size_max) {
int Uart::receive(char *data, int size_max) {
int received = 0; int received = 0;
#ifdef DEBUG
// printf("%s: receiving characters %d\r\n", __func__, size_max);
#endif
received = read(dev->fd, data, size_max - 1);
data[received] = '\0';
#ifdef DEBUG
// if(received > 0)
// printf("%s: received %d characters\r\n", __func__, received);
// else
// printf("%s: r%d/%d\r\n", __func__, received, size_max);
#endif
return received;
}
int uartStop(struct UartDevice *dev) {
free(dev->tty);
return UART_SUCCESS;
}
using namespace iflytop;
using namespace core;
Uart::Uart(const char *path, int rate) {
this->device.name = strdup(path);
this->device.rate = rate;
}
Uart::~Uart() {
if (this->device.name) free(this->device.name);
}
int Uart::start(unsigned char canonic) { return uartStart(&this->device, canonic); }
int Uart::send(char *data, int size) {
if (logger->level() <= level::debug) {
logger->debug("{} send: {}", this->device.name, StringUtils().bytesToString((const uint8_t *)data, size));
received = read(m_fd, data, size_max);
if (received < 0) {
m_error = fmt::format("read {} failed,{}", m_name, strerror(errno));
} }
return uartSend(&this->device, data, size);
}
int Uart::receive(char *data, int size_max) {
int ret = uartReceive(&this->device, data, size_max);
if (logger->level() <= level::debug) { if (logger->level() <= level::debug) {
if (ret > 0) {
logger->debug("{} receive: {}[{}]", this->device.name, StringUtils().bytesToString((const uint8_t *)data, ret));
}
logger->debug("{} receive: {}", m_name, StringUtils().bytesToString((const uint8_t *)data, received));
} }
return ret;
}
int Uart::stop() {
int rc = uartStop(&this->device);
return rc;
}
bool Uart::flush_rx() {
int rc = tcflush(this->device.fd, TCIFLUSH);
return rc == 0;
}
bool Uart::flush_tx() {
int rc = tcflush(this->device.fd, TCOFLUSH);
return rc == 0;
}
/**
* @brief Set the rx overtime object
*
* @param n100ms 100ms0
* @return true
* @return false
*/
bool Uart::set_rx_overtime(int n100ms) {
this->device.tty->c_cc[VTIME] = n100ms;
int rc = tcsetattr(this->device.fd, TCSANOW, this->device.tty);
return rc == 0;
return received;
} }
int Uart::receive(char *data, int size, int overtimems) { int Uart::receive(char *data, int size, int overtimems) {
if (m_fd < 0) return -1;
tp_steady now = tu_steady().now(); tp_steady now = tu_steady().now();
tp_steady end = now + std::chrono::milliseconds(overtimems); tp_steady end = now + std::chrono::milliseconds(overtimems);
int rc = 0; int rc = 0;
int total = 0; int total = 0;
while (now < end) { while (now < end) {
rc = uartReceive(&this->device, data + total, size - total);
rc = receive(data + total, size - total);
if (rc > 0) { if (rc > 0) {
total += rc; total += rc;
if (total >= size) break; if (total >= size) break;
@ -250,3 +135,24 @@ int Uart::receive(char *data, int size, int overtimems) {
} }
return total; return total;
} }
int Uart::close() {
::close(m_fd);
m_fd = -1;
return 0;
}
bool Uart::flush_rx() {
if (m_fd < 0) return false;
int rc = tcflush(m_fd, TCIFLUSH);
return rc == 0;
}
bool Uart::flush_tx() {
if (m_fd < 0) return false;
int rc = tcflush(m_fd, TCOFLUSH);
return rc == 0;
}
bool Uart::set_rx_overtime(int n100ms) {
if (m_fd < 0) return false;
m_tty.c_cc[VTIME] = n100ms;
int rc = tcsetattr(this->m_fd, TCSANOW, &m_tty);
return rc == 0;
}

65
core/components/uart/uart.hpp

@ -14,17 +14,6 @@
#include <vector> #include <vector>
#include "iflytopcpp/core/spdlogfactory/logger.hpp" #include "iflytopcpp/core/spdlogfactory/logger.hpp"
#define UART_FAILURE -1
#define UART_SUCCESS 0
struct UartDevice {
char *name;
int rate;
int fd;
struct termios *tty;
};
namespace iflytop { namespace iflytop {
namespace core { namespace core {
using namespace std; using namespace std;
@ -35,44 +24,42 @@ class Uart {
private: private:
/* data */ /* data */
UartDevice device = {0};
int m_fd = 0;
string m_name;
string m_rate;
struct termios m_tty;
string m_error;
public: public:
Uart(const char *path, int rate);
Uart();
~Uart(); ~Uart();
/*
Parameters:
struct UartDevice* dev - pointer to the UartDevice struct
unsigned char canonic - communication mode
1 - canonic communication (chars are only received after \n is detected).
0 - non canonic communication (chars are received as they arrive over UART).
Return value:
UART_FAILURE -1 failure
UART_SUCCESS 0 success
Description:
Initializes the UART device.
When calling the function, the device name (usually "/dev/ttyUL1") must be filled in dev->name and the baud
rate must be filled in dev->rate. The canonic function parameter indicates communication mode (canonic or not). In the
canonic communication mode, the received chars can be retrieved by read only after \n is detected. In the non canonic
communication mode, the received chars can be retrieved by read as they are received, as the non canonic mode is
configured with no wait.
/**
* @brief
*
* @param path
* @param rate
* "0" "50" "75" "110"
* "134" "150" "200" "300"
* "600" "1200" "1800" "2400"
* "4800" "9600" "19200" "38400"
* "57600" "115200" "230400" "460800"
* "500000" "576000" "921600" "1000000"
* "1152000" "1500000" "2000000" "2500000"
* "3000000" "3500000" "4000000"
*
* @return int
*/ */
int start(unsigned char canonic = 0);
int open(string path, string rate);
int send(char *data, int size); int send(char *data, int size);
int receive(char *data, int size_max); int receive(char *data, int size_max);
int stop();
int receive(char *data, int size, int overtimems); int receive(char *data, int size, int overtimems);
int close();
string get_error() { return m_error; }
bool flush_rx(); bool flush_rx();
bool flush_tx(); bool flush_tx();
/**
* @brief Set the rx overtime object
*
* @param n100ms 100ms0
* @return true
* @return false
*/
bool set_rx_overtime(int n100ms); bool set_rx_overtime(int n100ms);
}; };

110
core/zexception/zexception.cpp

@ -3,113 +3,23 @@
// //
#include "zexception.hpp" #include "zexception.hpp"
#if ENABLE_BACK_WARD
#include "../utils/backward/backward.hpp"
#endif
#include <stdarg.h> #include <stdarg.h>
#include "spdlog/spdlog.h"
#include <iostream> #include <iostream>
#include <thread> #include <thread>
// #include "zwtimecpp/core/base/interlog/simple_logger.hpp"
// #include "zwtimecpp/core/exception_handle_center.hpp"
// #include "zwtimecpp/core/logger/logger.hpp"
// #include "zwtimecpp/core/system_state.hpp"
#include "spdlog/spdlog.h"
using namespace std; using namespace std;
using namespace iflytop; using namespace iflytop;
using namespace core; using namespace core;
#if ENABLE_BACK_WARD
using namespace backward;
#endif
static shared_ptr<zexception> s_theLastedBaseException;
void zexception::setLastException(shared_ptr<zexception> e) { s_theLastedBaseException = e; }
shared_ptr<zexception> zexception::getUnHandledException() {
if (s_theLastedBaseException && !s_theLastedBaseException->isHasCalledToString()) {
return s_theLastedBaseException;
}
if (s_theLastedBaseException) {
return s_theLastedBaseException;
}
return nullptr;
}
zexception::zexception(string description, string stdExceptionTypeinfo, string baseExceptionWhat) {
initialize(description, stdExceptionTypeinfo, baseExceptionWhat);
};
void zexception::initialize(string description, string stdExceptionTypeinfo, string baseExceptionWhat) {
#if ENABLE_BACK_WARD
StackTrace st;
st.load_here(32);
Printer p;
p.object = true;
p.snippet = true;
p.color_mode = ColorMode::always;
p.address = true;
ostringstream out;
p.print(st, out);
#endif
this->description = description;
#if ENABLE_BACK_WARD
this->stackInfo = out.str();
#else
this->stackInfo = "not enable back ward";
#endif
this->pthreadId = pthread_self();
this->stdExceptionWhat = baseExceptionWhat;
this->stdExceptionTypeinfo = stdExceptionTypeinfo;
// setLastException(shared_from_this());
}
zexception::zexception(string description) {
m_description = description;
zexception::zexception(string description, const std::exception &stdexcep) {
initialize(description, typeid(stdexcep).name(), stdexcep.what());
// 这里不能写成
// zexception(description,typeid(stdexcep).name(),stdexcep.what());
// 不知道为什么对象的成员变量会被清空
}
string zexception::format1024(const char *fmt, ...) {
char buf[1024] = {0};
va_list args;
va_start(args, fmt);
vsnprintf(buf, 1024, fmt, args);
va_end(args);
return string(buf);
}
string zexception::toString() const {
string ret;
ret +=
"\n#-----------------------!!!!!CatchException!!!!!----------------------"
"-------\n";
ret += "# exception type: " + string(typeid(*this).name()) + "\n";
ret += "# description: " + this->description + "\n";
if (!this->stdExceptionTypeinfo.empty()) ret += "# stdExceptionTypeinfo: " + this->stdExceptionTypeinfo + "\n";
if (!this->stdExceptionWhat.empty()) ret += "# stdExceptionWhat: " + this->stdExceptionWhat + "\n";
string threadInfo;
// ret += "#pthreadId: " + CoreSystemState::Instance().get
//(this->pthreadId) + "\n";
ret += "# loseInfo: " + to_string(this->loseInfo) + "\n";
ret += "# stackTrace: \n" + this->stackInfo;
hasCalledToString = true;
return ret;
}
zexception::~zexception() {
if (!hasCalledToString) {
std::cerr << "#Show exception message, because not call "
"exception->toString before it destroy";
std::cerr << toString();
}
}
bool zexception::isHasCalledToString() const { return hasCalledToString; }
const char *zexception::what() const _GLIBCXX_USE_NOEXCEPT {
// return toString().c_str();
// 之所以在这里打印log,因为在arm上由系统自动打印的,what()可能会出现乱码.
spdlog::critical("Catch exception \n{}", toString());
spdlog::default_logger()->flush();
return "end";
m_what += "\n=======================Exception=======================\n";
m_what += "= Description: " + m_description + "\n";
m_what += "=";
} }
zexception::~zexception() {}
const char *zexception::what() const _GLIBCXX_USE_NOEXCEPT { return m_what.c_str(); }

57
core/zexception/zexception.hpp

@ -20,62 +20,13 @@ namespace iflytop {
namespace core { namespace core {
using namespace std; using namespace std;
/**
* 1. (ok)
* 2. 使 ( )
* 3.
* 4.
* 5. 线
*/
class zexception : public std::exception { class zexception : public std::exception {
protected:
string stackInfo;
string description;
pthread_t pthreadId;
bool loseInfo = false; // 这个
string stdExceptionWhat;
string stdExceptionTypeinfo;
protected:
mutable bool hasCalledToString = false;
public: // Getter
virtual const string &getStackInfo() const { return stackInfo; }
virtual const string &getDescription() const { return description; }
bool isHasCalledToString() const;
virtual pthread_t getPthreadId() const { return pthreadId; }
virtual bool isLoseInfo() const { return loseInfo; }
virtual void setLoseInfo(bool loseInfo) { zexception::loseInfo = loseInfo; }
const char *what() const _GLIBCXX_USE_NOEXCEPT override;
public: public:
/**
* ,
*
* : toString, toString, ,
* BaseException的异常会被忽悠掉
* @param description
*/
zexception(string description, string stdExceptionTypeinfo = "", string baseExceptionWhat = "");
zexception(string description, const std::exception &stdexcep);
string m_description;
string m_what;
zexception(string description);
virtual ~zexception(); virtual ~zexception();
virtual string toString() const;
/**
* ,1024
* @param fmt
* @param ...
* @return
*/
static string format1024(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
static void setLastException(shared_ptr<zexception> e);
static shared_ptr<zexception> getUnHandledException();
private:
void initialize(string description, string stdExceptionTypeinfo = "", string baseExceptionWhat = "");
const char *what() const _GLIBCXX_USE_NOEXCEPT;
}; };
} // namespace core } // namespace core
} // namespace iflytop } // namespace iflytop
Loading…
Cancel
Save