Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- **C++ SDK:** `asset::AssetContext` (`statements` / `statement_download_url`) is now actually built and usable. `longbridge.hpp` has always included `asset_context.hpp`, but `cpp/src/asset_context.cpp` was never listed in `cpp/CMakeLists.txt`, so the class was declared to users and then failed to link. It had also never compiled: it included neither `longbridge.h` nor the C declarations, and `statement_download_url` read `res->data` as a `lb_statement_download_url_response_t*` — a type that does not exist anywhere in the C layer, which delivers the URL as a bare `const char*` (the same convention as `QuoteContext::quote_level`). Fixed the include and the callback, and added the file to the build
- **C SDK:** export `lb_statement_item_t` from `longbridge.h`. `CStatementItem` is only reachable through the `void*` async-result pointer, so cbindgen did not emit it and no C or C++ caller could read what `lb_asset_context_statements` returns. Also added the missing `CAssetContext` → `lb_asset_context_t` entry to the cbindgen rename map: every other context type was mapped, so the header exposed the raw Rust name (`const struct CAssetContext *lb_asset_context_new(...)`) while the C++ side forward-declared `lb_asset_context_t`
- **C/C++ SDKs:** every list argument that crosses the FFI boundary now tolerates a null pointer with a zero length. `std::vector::data()` is allowed to return `nullptr` for an empty vector, which is exactly what the C++ binding passes for an omitted list argument, but the C layer fed it straight to `std::slice::from_raw_parts` — undefined behaviour that **aborts the process** under the debug UB checks. Hit live by `QuoteContext::warrant_list` with no filters (`c/src/quote_context/context.rs`); all 17 call sites across `quote_context`, `trade_context`, `agent_context`, `alert_context`, and `types` now go through a null-tolerant `slice_from_raw_parts` helper

### Added
Expand Down
4 changes: 4 additions & 0 deletions c/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ cpp_compat = true
"CCalendarContext" = "lb_calendar_context_t"
"CPortfolioContext" = "lb_portfolio_context_t"
"CMarketContext" = "lb_market_context_t"
"CAssetContext" = "lb_asset_context_t"
"CStatementItem" = "lb_statement_item_t"
# MarketContext types
"CMarketTimeItem" = "lb_market_time_item_t"
"CMarketStatusResponse" = "lb_market_status_response_t"
Expand Down Expand Up @@ -428,6 +430,8 @@ include = [
"CWatchlistSecurity",
"CMarginRatio",
"COrderDetail",
# AssetContext: statements (reachable only via void* async data pointer)
"CStatementItem",
# GridContext: grid trading (reachable only via void* async data pointer)
"CSubmitGridOrderResponse",
"CGridOrder", "CGridOrderSubOrder", "CGridOrderHistory", "CGridOrderDetail",
Expand Down
26 changes: 20 additions & 6 deletions c/csrc/include/longbridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -1853,7 +1853,7 @@ typedef struct lb_alert_context_t lb_alert_context_t;
/**
* Asset context
*/
typedef struct CAssetContext CAssetContext;
typedef struct lb_asset_context_t lb_asset_context_t;

typedef struct lb_calendar_context_t lb_calendar_context_t;

Expand Down Expand Up @@ -6065,6 +6065,20 @@ typedef struct lb_order_detail_t {
struct CMultiLegInfo multi_leg;
} lb_order_detail_t;

/**
* Statement item
*/
typedef struct lb_statement_item_t {
/**
* Statement date (integer, e.g. 20250301)
*/
int32_t dt;
/**
* File key
*/
const char *file_key;
} lb_statement_item_t;

/**
* Response for submit grid trading order request
*/
Expand Down Expand Up @@ -11862,17 +11876,17 @@ void lb_alert_context_delete(const struct lb_alert_context_t *ctx,
* @param config Config object
* @return A new asset context
*/
const struct CAssetContext *lb_asset_context_new(const struct lb_config_t *config);
const struct lb_asset_context_t *lb_asset_context_new(const struct lb_config_t *config);

/**
* Retain the asset context (increment reference count)
*/
void lb_asset_context_retain(const struct CAssetContext *ctx);
void lb_asset_context_retain(const struct lb_asset_context_t *ctx);

/**
* Release the asset context (decrement reference count)
*/
void lb_asset_context_release(const struct CAssetContext *ctx);
void lb_asset_context_release(const struct lb_asset_context_t *ctx);

/**
* Get statement data list
Expand All @@ -11884,7 +11898,7 @@ void lb_asset_context_release(const struct CAssetContext *ctx);
* @param callback Async callback
* @param userdata User data passed to the callback
*/
void lb_asset_context_statements(const struct CAssetContext *ctx,
void lb_asset_context_statements(const struct lb_asset_context_t *ctx,
int32_t statement_type,
int32_t start_date,
int32_t limit,
Expand All @@ -11899,7 +11913,7 @@ void lb_asset_context_statements(const struct CAssetContext *ctx,
* @param callback Async callback
* @param userdata User data passed to the callback
*/
void lb_asset_context_download_url(const struct CAssetContext *ctx,
void lb_asset_context_download_url(const struct lb_asset_context_t *ctx,
const char *file_key,
lb_async_callback_t callback,
void *userdata);
Expand Down
1 change: 1 addition & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set(SOURCES
src/decimal.cpp
src/agent_context.cpp
src/alert_context.cpp
src/asset_context.cpp
src/dca_context.cpp
src/sharelist_context.cpp
src/calendar_context.cpp
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/asset_context.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "asset_context.hpp"
#include "longbridge.h"
#include <algorithm>
#include <iterator>

Expand Down Expand Up @@ -122,9 +123,8 @@ AssetContext::statement_download_url(
Status status(res->error);

if (status) {
auto resp = (const lb_statement_download_url_response_t*)res->data;
StatementDownloadUrlResponse result;
result.url = resp->url;
result.url = (const char*)res->data;

(*callback_ptr)(
AsyncResult<AssetContext, StatementDownloadUrlResponse>(
Expand Down