Conversation
timkpaine
force-pushed
the
tkp/capi
branch
7 times, most recently
from
February 18, 2026 04:16
fdc5893 to
39e2929
Compare
timkpaine
force-pushed
the
tkp/capi
branch
2 times, most recently
from
February 18, 2026 21:58
ede3e85 to
c845c31
Compare
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Memory safety: - Guard every push entry point against a type that does not match the adapter's declared CspType, which previously reinterpreted the value's bytes on the engine thread. - Validate that a StructField handle belongs to the struct it is applied to, accepting overridden inherited fields that share the base layout. - Reject a null data pointer with a non-zero length rather than constructing std::string from it. - Hold a reference to the PushGroup capsule for as long as the engine keeps its raw pointer. - Contain exceptions at both directions of the boundary: every extern "C" entry point, and every invocation of a user callback. Destructors and name() swallow, since they cannot throw. ABI: - Add abi_version and struct_size to every callback table and adopt them size-tolerantly, so a table built against an older header is copied as far as it goes and zero-filled beyond. - Give every public enum explicit values. - Use CCSP_DATETIME_NONE as the "no more sim data" sentinel; 0 is the valid Unix epoch. - Correct CCspStatusLevel, which was inverted relative to csp.adapters.status.Level. - Build the C API shims into cspimpl so CSP_C_API_EXPORT resolves to dllexport on Windows, removing the force_load/whole-archive workaround. Completeness: - Implement the 85 declared but undefined functions across CspTime, CspString, CspValue and the indexed input accessors, and export them. - Implement the remaining NOT_IMPLEMENTED stubs, including nested struct reads, enum writes, struct and generic value pushes, and the managed sim input adapter. - Reject reads from inputs that have never ticked instead of returning a default-constructed value. Rust example: - Correct enum discriminants that did not match the C headers, and route every FFI return through a checked conversion so an unrecognized value cannot become an invalid enum. - Reject non-positive intervals and wait on a condition variable so stop interrupts the worker immediately. - Cache symbol lookups instead of resolving on every call. C example: - Replace the racy stop flag, the unconditional join, the mis-cast Windows thread entry, usleep and rand with a portable worker. Build and CI: - Make the example builds platform-portable and ship the import library Windows consumers link against. - Add a C API check that every exported declaration resolves, and that every public header compiles standalone as C11 and C++20. - Add gtest coverage for the time, string, value and ABI layers. - Pin the new actions by SHA and drop the retired duplicate cache. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
ErrorExtern.cpp defines ccsp_set_error but was only listed in the test_c_api target, so the six other C API translation units in cspimpl referenced an undefined symbol. ELF and Mach-O permit undefined symbols in a shared object and resolve them lazily, so the Linux and macOS wheels linked and only Windows failed, with LNK1120 on _cspimpl.pyd. The module would have raised ImportError on first use everywhere. Also define CSPIMPL_EXPORTS for test_c_api. That target compiles the C API sources itself, so without it CSP_C_API_EXPORT expands to dllimport for symbols the target defines locally, which MSVC reports as LNK4217 and LNK4286. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
The managed input bridge unpacked four scalars, but only kwargs become scalars: InputAdapterDef strips push_mode from the tail and AdapterDef strips the manager from the head, leaving (typ, interval_ms, push_group). That raised ValueError on macOS in test_cpp_examples. The managed output bridge had the same miscount, masked rather than raised: scalars is (prefix,), so `scalars[1] if len(scalars) > 1 else ""` always took the else branch and the manager's prefix was silently discarded on every call. Replace the defensive index lookups with strict unpacking in all four bridges so a future mismatch fails loudly instead of substituting a default. Verified the delivered tuples for each of the four adapter definitions against csp's wiring layer. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
check_c_api.py only searched the repository, so the example CI job failed with "could not locate the built extension module": that job installs a csp wheel and builds nothing in-tree. Search the repository first and fall back to csp.get_lib_path(). Repo first matters, otherwise an unrelated csp that happens to be installed is checked instead of the build under test, which reports every symbol as missing rather than failing outright. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
The example builds searched only for _cspimpl, but CMake applies the leading underscore to the module and not to its import library, so the wheel ships csp/lib/_cspimpl.pyd alongside csp/lib/cspimpl.lib. Every Windows example failed to configure with CSP_LIBRARY-NOTFOUND. Search both names, preferring the underscored one if a build ever produces it. Confirmed against the wheel from this branch: cspimpl.lib is present and exports both the C API symbols and the C++ symbols the older examples link. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Examples 1 through 3 declare add_library(... SHARED ...) and link only the csp module, so MSVC failed with LNK1104 on python311.lib: pyconfig.h emits a pragma naming the import library, but nothing put it on the link line. Example 4 already builds with Python_add_library, which links Python::Module for you, which is why it configured. Development.Module is already requested, so link the target it provides. On Windows it supplies pythonXY.lib; on Unix it deliberately links no libpython, leaving those symbols to the host interpreter. Verified on macOS that all three still build and that none gained a libpython reference. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
The C++ examples linked only the csp module, which left 20 unresolved externals on MSVC: csp::Node, csp::Engine, csp::TimeSeriesProvider, csp::StructMeta and friends are not dllexport'd, so they are absent from the module's import library. Unix links the module directly and sees every symbol, which is why this only surfaced on Windows. Link the static archives the wheel already ships, matching what csp's own extension modules do in cpp/csp/python/adapters/CMakeLists.txt. csptypesimpl is included as an import library because DialectGenericType is declared dllimport and so cannot be satisfied by a static archive. Mapped each unresolved symbol group to its providing archive using the Windows wheel built from this branch, and confirmed all four names resolve under MSVC library naming. macOS is unaffected: the variable is empty off Windows and all three examples still build. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
ExampleOutputAdapter.c included unistd.h and wrote through dprintf on a file descriptor, neither of which MSVC provides, so the Windows build failed with C1083 on unistd.h. Write to a FILE * with fprintf instead. That is standard C rather than POSIX, so it needs no platform branch, and the file descriptor was incidental to what the example teaches. example_output_adapter_create_fd becomes example_output_adapter_create_stream; it had no callers outside this file. Checked the example's other C sources for the same assumption; the only other POSIX include is pthread.h, already guarded for _WIN32. Verified the example builds and its 4 tests pass. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
dumpbin only exists inside a Visual Studio developer environment, which the CI runner never enters, so the symbol check died with WinError 2 after the example had built and passed its tests. Parse the PE export name table instead. It needs no toolchain, so the check keeps working wherever Python runs, and Windows is the platform this check exists to cover: it is the one that can silently fail to export a symbol. Validated against the win_amd64 wheel built from this branch, read on macOS: 252 exports, of which 219 are ccsp_, matching the 219 declared symbols exactly. Non-PE input is rejected rather than misparsed. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a C API for ABI stability for external adapters. This should let us (and others) create adapters separate from the csp build process in a stable way.