Revert "[Mod]new pybind11 wrap"

This reverts commit 416f2a1e17.
This commit is contained in:
vn.py 2019-04-25 19:14:56 +08:00
parent 416f2a1e17
commit ee4f690e26
8 changed files with 98 additions and 254 deletions

View File

@ -7,34 +7,19 @@ if typing.TYPE_CHECKING:
from .vnxtp import *
def set_async_callback_exception_handler(handler: Callable[[AsyncDispatchException], None]):
"""
set a customize exception handler for async callback in this module(pyd)
\a handler should return True if it handles that exception,
If the return value of \a handler is not True, exception will be re-thrown.
"""
...
class AsyncDispatchException:
what: str
instance: object
function_name: str
from . import vnxtp_XTP as XTP
class XTPRspInfoStruct():
error_id: int
error_msg: str
error_msg: Sequence[int]
class XTPSpecificTickerStruct():
exchange_id: XTP_EXCHANGE_TYPE
ticker: str
ticker: Sequence[int]
class XTPMarketDataStockExData():
@ -86,7 +71,7 @@ class XTPMarketDataStruct():
exchange_id: XTP_EXCHANGE_TYPE
ticker: str
ticker: Sequence[int]
last_price: float
pre_close_price: float
open_price: float
@ -110,7 +95,7 @@ class XTPMarketDataStruct():
bid_qty: Sequence[int]
ask_qty: Sequence[int]
trades_count: int
ticker_status: str
ticker_status: Sequence[int]
stk: XTPMarketDataStockExData
opt: XTPMarketDataOptionExData
data_type: XTP_MARKETDATA_TYPE
@ -121,8 +106,8 @@ class XTPQuoteStaticInfo():
exchange_id: XTP_EXCHANGE_TYPE
ticker: str
ticker_name: str
ticker: Sequence[int]
ticker_name: Sequence[int]
ticker_type: XTP_TICKER_TYPE
pre_close_price: float
upper_limit_price: float
@ -136,7 +121,7 @@ class OrderBookStruct():
exchange_id: XTP_EXCHANGE_TYPE
ticker: str
ticker: Sequence[int]
last_price: float
qty: int
turnover: float
@ -176,7 +161,7 @@ class XTPTickByTickStruct():
exchange_id: XTP_EXCHANGE_TYPE
ticker: str
ticker: Sequence[int]
seq: int
data_time: int
type: XTP_TBT_TYPE
@ -188,7 +173,7 @@ class XTPTickerPriceInfo():
exchange_id: XTP_EXCHANGE_TYPE
ticker: str
ticker: Sequence[int]
last_price: float
@ -197,7 +182,7 @@ class XTPOrderInsertInfo():
order_xtp_id: int
order_client_id: int
ticker: str
ticker: Sequence[int]
market: XTP_MARKET_TYPE
price: float
stop_price: float
@ -225,7 +210,7 @@ class XTPOrderInfo():
order_client_id: int
order_cancel_client_id: int
order_cancel_xtp_id: int
ticker: str
ticker: Sequence[int]
market: XTP_MARKET_TYPE
price: float
quantity: int
@ -242,7 +227,7 @@ class XTPOrderInfo():
update_time: int
cancel_time: int
trade_amount: float
order_local_id: str
order_local_id: Sequence[int]
order_status: XTP_ORDER_STATUS_TYPE
order_submit_status: XTP_ORDER_SUBMIT_STATUS_TYPE
order_type: int
@ -253,16 +238,16 @@ class XTPTradeReport():
order_xtp_id: int
order_client_id: int
ticker: str
ticker: Sequence[int]
market: XTP_MARKET_TYPE
local_order_id: int
exec_id: str
exec_id: Sequence[int]
price: float
quantity: int
trade_time: int
trade_amount: float
report_index: int
order_exch_id: str
order_exch_id: Sequence[int]
trade_type: int
u32: int
side: int
@ -270,13 +255,13 @@ class XTPTradeReport():
reserved1: int
reserved2: int
business_type: XTP_BUSINESS_TYPE
branch_pbu: str
branch_pbu: Sequence[int]
class XTPQueryOrderReq():
ticker: str
ticker: Sequence[int]
begin_time: int
end_time: int
@ -285,13 +270,13 @@ class XTPQueryReportByExecIdReq():
order_xtp_id: int
exec_id: str
exec_id: Sequence[int]
class XTPQueryTraderReq():
ticker: str
ticker: Sequence[int]
begin_time: int
end_time: int
@ -326,8 +311,8 @@ class XTPQueryAssetRsp():
class XTPQueryStkPositionRsp():
ticker: str
ticker_name: str
ticker: Sequence[int]
ticker_name: Sequence[int]
market: XTP_MARKET_TYPE
total_qty: int
sellable_qty: int
@ -365,17 +350,17 @@ class XTPQueryStructuredFundInfoReq():
exchange_id: XTP_EXCHANGE_TYPE
sf_ticker: str
sf_ticker: Sequence[int]
class XTPStructuredFundInfo():
exchange_id: XTP_EXCHANGE_TYPE
sf_ticker: str
sf_ticker_name: str
ticker: str
ticker_name: str
sf_ticker: Sequence[int]
sf_ticker_name: Sequence[int]
ticker: Sequence[int]
ticker_name: Sequence[int]
split_merge_status: XTP_SPLIT_MERGE_STATUS
ratio: int
min_split_qty: int
@ -387,15 +372,15 @@ class XTPQueryETFBaseReq():
market: XTP_MARKET_TYPE
ticker: str
ticker: Sequence[int]
class XTPQueryETFBaseRsp():
market: XTP_MARKET_TYPE
etf: str
subscribe_redemption_ticker: str
etf: Sequence[int]
subscribe_redemption_ticker: Sequence[int]
unit: int
subscribe_status: int
redemption_status: int
@ -410,16 +395,16 @@ class XTPQueryETFComponentReq():
market: XTP_MARKET_TYPE
ticker: str
ticker: Sequence[int]
class XTPQueryETFComponentRsp():
market: XTP_MARKET_TYPE
ticker: str
component_ticker: str
component_name: str
ticker: Sequence[int]
component_ticker: Sequence[int]
component_name: Sequence[int]
quantity: int
component_market: XTP_MARKET_TYPE
replace_type: ETF_REPLACE_TYPE
@ -431,8 +416,8 @@ class XTPQueryIPOTickerRsp():
market: XTP_MARKET_TYPE
ticker: str
ticker_name: str
ticker: Sequence[int]
ticker_name: Sequence[int]
price: float
unit: int
qty_upper_limit: int
@ -449,17 +434,17 @@ class XTPQueryOptionAuctionInfoReq():
market: XTP_MARKET_TYPE
ticker: str
ticker: Sequence[int]
class XTPQueryOptionAuctionInfoRsp():
ticker: str
ticker: Sequence[int]
security_id_source: XTP_MARKET_TYPE
symbol: str
contract_id: str
underlying_security_id: str
symbol: Sequence[int]
contract_id: Sequence[int]
underlying_security_id: Sequence[int]
underlying_security_id_source: XTP_MARKET_TYPE
list_date: int
last_trade_date: int
@ -498,8 +483,8 @@ class XTPFundTransferReq():
serial_id: int
fund_account: str
password: str
fund_account: Sequence[int]
password: Sequence[int]
amount: float
transfer_type: XTP_FUND_TRANSFER_TYPE
@ -625,7 +610,7 @@ class XTP_POSITION_DIRECTION_TYPE(Enum):
class XTP_MARKETDATA_TYPE(Enum):
XTP_MARKETDATA_ACTUAL: XTP_MARKETDATA_TYPE
XTP_MARKETDATA_OPTION: XTP_MARKETDATA_TYPE
XTPVersionType = str
XTPVersionType = Sequence[int]
XTP_LOG_LEVEL = XTP_LOG_LEVEL
XTP_PROTOCOL_TYPE = XTP_PROTOCOL_TYPE
XTP_EXCHANGE_TYPE = XTP_EXCHANGE_TYPE

View File

@ -277,14 +277,9 @@ void generate_class_XTP_API_QuoteApi(pybind11::object & parent)
PyQuoteApi
> c(parent, "QuoteApi");
c.def_static("CreateQuoteApi",
autocxxpy::apply_function_transform<
autocxxpy::function_constant<
&XTP::API::QuoteApi::CreateQuoteApi
>,
brigand::list<
>
>::value,
pybind11::call_guard<pybind11::gil_scoped_release>()
//,
//pybind11::call_guard<pybind11::gil_scoped_release>()
);
c.def("Release",
autocxxpy::apply_function_transform<

View File

@ -1,7 +1,6 @@
#include <iostream>
#include <string>
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <autocxxpy/autocxxpy.hpp>
#include "module.hpp"
@ -21,12 +20,6 @@ void additional_init(pybind11::module &m)
void init_dispatcher(pybind11::module &m)
{
m.def("set_async_callback_exception_handler", &autocxxpy::async_callback_exception_handler::set_handler);
pybind11::class_<autocxxpy::async_dispatch_exception> c(m, "AsyncDispatchException");
c.def_property("what", &autocxxpy::async_dispatch_exception::what, nullptr);
c.def_readonly("instance", &autocxxpy::async_dispatch_exception::instance);
c.def_readonly("function_name", &autocxxpy::async_dispatch_exception::function_name);
autocxxpy::dispatcher::instance().start();
}

View File

@ -2,7 +2,6 @@
#include <tuple>
#include <type_traits>
#include <optional>
#include "brigand.hpp"
@ -67,7 +66,7 @@ namespace autocxxpy
template <auto method>
constexpr callback_type callback_type_of_v = callback_type_of<method>::value;
#ifdef AUTOCXXPY_INCLUDED_PYBIND11
#ifdef PYBIND11_OVERLOAD_NAME
template <class ret_type>
struct pybind11_static_caster {
static pybind11::detail::overload_caster_t<ret_type> caster;
@ -76,59 +75,18 @@ namespace autocxxpy
template <class ret_type>
AUTOCXXPY_SELECT_ANY pybind11::detail::overload_caster_t<ret_type> pybind11_static_caster<ret_type>::caster;
struct async_dispatch_exception : public std::exception
{
async_dispatch_exception(const char *what, const pybind11::object &instance, std::string function_name)
: std::exception(what), instance(instance), function_name(function_name)
{}
pybind11::object instance;
std::string function_name;
inline const char* what() noexcept
{
return std::exception::what();
}
};
struct async_callback_exception_handler
{
using handler_type = std::function<void(const async_dispatch_exception&)>;
static handler_type custom_handler;
inline static void handle_excepiton(const async_dispatch_exception&e)
{
if (custom_handler)
{
custom_handler(e);
}
}
inline static void set_handler(const handler_type& handler)
{
custom_handler = handler;
}
};
AUTOCXXPY_SELECT_ANY async_callback_exception_handler::handler_type async_callback_exception_handler::custom_handler;
#endif
namespace arg_helper
{
//////////////////////////////////////////////////////////////////////////
// stores
//////////////////////////////////////////////////////////////////////////
// # todo: char8, char16, char32, wchar_t, etc...
// # todo: shall i copy only const type, treating non-const type as output pointer?
inline std::optional<std::string> save(const char* val)
inline auto save(const char *val)
{ // match const char *
if (nullptr == val) AUTOCXXPY_UNLIKELY
return std::nullopt; // maybe empty string is also a choice?
return std::string(val);
}
inline std::optional<std::string> save(char* val)
inline auto save(char *val)
{ // match char *
if (nullptr == val) AUTOCXXPY_UNLIKELY
return std::nullopt; // maybe empty string is also a choice?
return std::string(val);
}
template<size_t size>
@ -143,41 +101,29 @@ namespace autocxxpy
}
template <class T>
inline std::optional<T> save(T * val)
inline T &save(T *val)
{ // match pointer
if (nullptr == val) AUTOCXXPY_UNLIKELY
{
return std::nullopt;
}
return *val;
}
template <class T>
inline std::optional<T>& save(const T * val)
inline T &save(const T *val)
{ // match const pointer
if (nullptr == val) AUTOCXXPY_UNLIKELY
{
return std::nullopt;
}
return const_cast<T&>(*val);
}
template <class T>
inline T& save(const T & val)
inline T &save(const T &val)
{ // match everything else : just use original type
return const_cast<T&>(val);
}
//////////////////////////////////////////////////////////////////////////
// loads
//////////////////////////////////////////////////////////////////////////
template <class to_type>
struct loader
{ // match default(everyting besides pointer)
template <class src_type>
inline to_type operator ()(src_type& val)
inline to_type operator ()(src_type &val)
{
return val;
}
@ -186,57 +132,57 @@ namespace autocxxpy
template <size_t size>
struct loader<const string_array<size>>
{ // match const char []
using to_type = const char*;
inline to_type operator ()(const std::string& val)
using to_type = const char *;
inline to_type operator ()(const std::string &val)
{
return const_cast<char*>(val.data());
return const_cast<char *>(val.data());
}
};
template <size_t size>
struct loader<string_array<size>>
{ // match char []
using to_type = char*;
inline to_type operator ()(const std::string& val)
using to_type = char *;
inline to_type operator ()(const std::string &val)
{
return const_cast<char*>(val.data());
return const_cast<char *>(val.data());
}
};
template <>
struct loader<const char*>
struct loader<const char *>
{ // match const char *
using to_type = const char*;
inline to_type operator ()(const std::optional<std::string>& val)
using to_type = const char *;
inline to_type operator ()(const std::string &val)
{
if (val) AUTOCXXPY_LIKELY
return const_cast<char*>(val->data());
return nullptr;
return const_cast<char *>(val.data());
}
};
template <>
struct loader<char*>
struct loader<char *>
{ // match char *
using to_type = char*;
inline to_type operator ()(const std::optional<std::string>& val)
using to_type = char *;
inline to_type operator ()(const std::string &val)
{
if (val) AUTOCXXPY_LIKELY
return const_cast<char*>(val->data());
return nullptr;
return const_cast<char *>(val.data());
}
};
template <class to_type>
struct loader<to_type*>
struct loader<to_type *>
{ // match pointer
template <class src_type>
inline to_type* operator ()(const std::optional<src_type>& val)
inline to_type *operator ()(src_type &val)
{ // val to poiner
if (val) AUTOCXXPY_LIKELY
return const_cast<to_type*>(&(*val));
return nullptr;
return const_cast<to_type *>(&val);
}
//template <class src_type>
//inline to_type *operator ()(src_type *val)
//{ // pointer to pointer
// return val;
//}
};
};
@ -249,7 +195,7 @@ namespace autocxxpy
using class_type = class_of_member_method_t<method>;
public:
template <class ... arg_types>
inline static ret_type call(class_type* instance, const char* py_func_name, arg_types ... args)
inline static ret_type call(class_type *instance, const char *py_func_name, arg_types ... args)
{
if constexpr (callback_type_of_v<method> == callback_type::Direct)
{
@ -265,70 +211,47 @@ namespace autocxxpy
}
template <class ... arg_types>
inline static void async(class_type* instance, const char* py_func_name, arg_types ... args)
inline static void async(class_type *instance, const char *py_func_name, arg_types ... args)
{
return async_impl(instance, py_func_name, std::index_sequence_for<arg_types ...>{}, args ...);
}
template <class ... arg_types>
inline static ret_type sync(class_type * instance, const char* py_func_name, arg_types ... args)
inline static ret_type sync(class_type *instance, const char * py_func_name, arg_types ... args)
{
// if this code is under test environment, we don't need pybind11
// since header of pybind11 use #pragma once, no macros is defined, we use a public macro to check if pybind11 is included or not
#ifdef PYBIND11_OVERLOAD_NAME
pybind11::gil_scoped_acquire gil;
pybind11::function overload = pybind11::get_overload(static_cast<const class_type*>(instance), py_func_name);
if (overload) AUTOCXXPY_LIKELY{
try
{
auto result = overload(args ...);
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value)
{
auto& caster = pybind11_static_caster<ret_type>::caster;
return pybind11::detail::cast_ref<ret_type>(std::move(result), caster);
}
else
{
return pybind11::detail::cast_safe<ret_type>(std::move(result));
}
}
catch (const pybind11::error_already_set & e)
{
// todo: option to not to throw when sync is called directly
throw async_dispatch_exception(e.what(), pybind11::cast(instance), py_func_name);
pybind11::function overload = pybind11::get_overload(static_cast<const class_type *>(instance), py_func_name);
if (overload) {
auto o = overload(args ...);
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) {
auto & caster = pybind11_static_caster<ret_type>::caster;
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster);
}
else return pybind11::detail::cast_safe<ret_type>(std::move(o));
}
#endif
return (instance->*method)(args ...);
}
private:
template <class ... arg_types, size_t ... idx>
inline static void async_impl(class_type * instance, const char* py_func_name, std::index_sequence<idx ...>, arg_types ... args)
inline static void async_impl(class_type *instance, const char *py_func_name, std::index_sequence<idx ...>, arg_types ... args)
{
// wrap for ctp like function calls:
// all the pointer might be unavailable after this call, so copy its value into a tuple
auto arg_tuple = std::make_tuple(arg_helper::save(args) ...);
auto task = [instance, py_func_name, arg_tuple = std::move(arg_tuple)]()
{
#ifdef AUTOCXXPY_INCLUDED_PYBIND11
try
{
#endif
// resolve all value:
// if it was originally a pointer, then use pointer type.
// if it was originally a value, just keep a reference to that value.
sync<arg_types ...>(
instance, py_func_name,
arg_helper::loader<brigand::at<brigand::list<arg_types ...>, brigand::integral_constant<int, idx> > >{}
(std::get<idx>(arg_tuple)) ...
);
#ifdef AUTOCXXPY_INCLUDED_PYBIND11
}
catch (const async_dispatch_exception &e)
{
async_callback_exception_handler::handle_excepiton(e);
}
#endif
// resolve all value:
// if it was originally a pointer, then use pointer type.
// if it was originally a value, just keep a reference to that value.
sync<arg_types ...>(
instance, py_func_name,
arg_helper::loader<brigand::at<brigand::list<arg_types ...>, brigand::integral_constant<int, idx> > >{}
(std::get<idx>(arg_tuple)) ...
);
};
dispatcher::instance().add(std::move(task));
}

View File

@ -8,30 +8,12 @@
#ifndef AUTOCXXPY_UNUSED
# define AUTOCXXPY_UNUSED(x) (void)(x)
#define AUTOCXXPY_UNUSED(x) (void)(x)
#endif
#ifdef _MSC_VER
# define AUTOCXXPY_SELECT_ANY __declspec(selectany)
#define AUTOCXXPY_SELECT_ANY __declspec(selectany)
#else
# define AUTOCXXPY_SELECT_ANY __attribute__ ((selectany))
#endif
#ifdef __has_cpp_attribute
# if __has_cpp_attribute(likely)
# define AUTOCXXPY_LIKELY [[likely]]
# endif
# if __has_cpp_attribute(unlikely)
# define AUTOCXXPY_UNLIKELY [[unlikely]]
# endif
#endif
#ifndef AUTOCXXPY_LIKELY
#define AUTOCXXPY_LIKELY
#endif
#ifndef AUTOCXXPY_UNLIKELY
#define AUTOCXXPY_UNLIKELY
#endif
#define AUTOCXXPY_SELECT_ANY __attribute__ ((selectany))
#endif

View File

@ -119,7 +119,6 @@
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -139,7 +138,6 @@
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -162,7 +160,6 @@
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -187,7 +184,6 @@
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -7,20 +7,5 @@ if typing.TYPE_CHECKING:
from .vnxtp import *
def set_async_callback_exception_handler(handler: Callable[[Exception, object, str], bool]):
"""
set a customize exception handler for async callback in this module(pyd)
\a handler should return True if it handles that exception,
If the return value of \a handler is not True, exception will be re-thrown.
"""
...
class AsyncDispatchException:
what: str
instance: object
function_name: str
from . import vnxtp_XTP_API as API

View File

@ -7,21 +7,6 @@ if typing.TYPE_CHECKING:
from .vnxtp import *
def set_async_callback_exception_handler(handler: Callable[[Exception, object, str], bool]):
"""
set a customize exception handler for async callback in this module(pyd)
\a handler should return True if it handles that exception,
If the return value of \a handler is not True, exception will be re-thrown.
"""
...
class AsyncDispatchException:
what: str
instance: object
function_name: str
class TraderSpi():