XTP: 从XTP看Rust与C++接口FFI通信

瘦欲@ 提交于 2020-10-24 13:35:31

XTP.rs 来源于:

https://github.com/dovahcrow/xtp-rs

一、从RUST ->C++:

当Rust需要把指令传入XTP中时,以register_spi为例

1、rust中.rs文件中

let mut api = QuoteApi::new(1, &args.path, XTPLogLevel::Trace);

info!("XTP Version: {:?}", api.get_api_version());
info!("Trading Day: {:?}", api.get_trading_day());

api.register_spi(MySpi);

2、quote_api.rs

pub fn register_spi<T: QuoteSpi>(&mut self, spi: T) {
    let trait_object_box: Box<Box<dyn QuoteSpi>> = Box::new(Box::new(spi));
    let trait_object_pointer =
        Box::into_raw(trait_object_box) as *mut Box<dyn QuoteSpi> as *mut c_void;

    let quote_spi_stub = unsafe { QuoteSpiStub::new(trait_object_pointer) };

    let ptr = Box::into_raw(Box::new(quote_spi_stub));
    self.quote_spi_stub = Some(ptr);
    unsafe { QuoteApi_RegisterSpi(self.quote_api, ptr as *mut XTP_API_QuoteSpi) };
}

(3)到 bind.rs =>

extern "C" {
    pub fn QuoteApi_RegisterSpi(self_: *mut XTP_API_QuoteApi, spi: *mut XTP_API_QuoteSpi);
}

(4)bridge.cpp

extern "C" void QuoteApi_RegisterSpi(XTP::API::QuoteApi *self, XTP::API::QuoteSpi *spi)
{
    auto s = static_cast<XTP::API::QuoteApi *>(self);
    return s->RegisterSpi(spi);
}

二、从C++ > RUST:

当 XTP有响应时,

以OnDepthMarketData为例:

(1)从头文件xtp_quote_api.h中QuoteSpi类

(2 )到 bridge.cpp中

实例QuoteSpiStub-> QuoteSpiStub::OnDepthMarketData ->

void QuoteSpiStub::OnDepthMarketData(XTPMD *market_data, int64_t bid1_qty[], int32_t bid1_count, int32_t max_bid1_count, int64_t ask1_qty[], int32_t ask1_count, int32_t max_ask1_count)
{
    return QuoteSpiStub_Rust_OnDepthMarketData(this->rust_object, market_data, bid1_qty, bid1_count, max_bid1_count, ask1_qty, ask1_count, max_ask1_count);
}

(3)到 Quotespi.rs =>

#[no_mangle]
pub unsafe extern "C" fn QuoteSpiStub_Rust_OnDepthMarketData(
    spi: *mut c_void,
    market_data: *const XTPMD,
    bid1_qty: *const i64,
    bid1_count: i32,
    max_bid1_count: i32,
    ask1_qty: *const i64,
    ask1_count: i32,
    max_ask1_count: i32,
) {
    let spi = unwrap_quote_spi(spi);

    let market_data = RXTPMD::from_raw(&*market_data);
    let bid1_qty = from_raw_parts(bid1_qty, bid1_count as usize);
    let ask1_qty = from_raw_parts(ask1_qty, ask1_count as usize);

    spi.on_depth_market_data(
        market_data,
        bid1_qty,
        max_bid1_count,
        ask1_qty,
        max_ask1_count,
    );
}

=>trait QuoteSpi =>分发给实现trait的对象

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!