{"id":21962515,"url":"https://github.com/biocpy/cpptypes","last_synced_at":"2025-10-10T10:32:02.118Z","repository":{"id":185122532,"uuid":"673039454","full_name":"BiocPy/cpptypes","owner":"BiocPy","description":"Automatically generate wrappers for ctypes with C++","archived":true,"fork":false,"pushed_at":"2023-09-08T14:15:54.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-25T12:26:43.616Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BiocPy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-31T18:20:39.000Z","updated_at":"2025-01-18T00:27:15.000Z","dependencies_parsed_at":"2024-11-29T10:42:55.088Z","dependency_job_id":"c7c0c0fe-2059-4361-b483-fb00ba2918de","html_url":"https://github.com/BiocPy/cpptypes","commit_stats":null,"previous_names":["biocpy/ctypes-wrapper"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/BiocPy/cpptypes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BiocPy%2Fcpptypes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BiocPy%2Fcpptypes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BiocPy%2Fcpptypes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BiocPy%2Fcpptypes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BiocPy","download_url":"https://codeload.github.com/BiocPy/cpptypes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BiocPy%2Fcpptypes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279003549,"owners_count":26083595,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T10:42:49.888Z","updated_at":"2025-10-10T10:32:01.810Z","avatar_url":"https://github.com/BiocPy.png","language":"Python","readme":"\u003c!-- These are examples of badges you might want to add to your README:\n     please update the URLs accordingly\n\n[![Built Status](https://api.cirrus-ci.com/github/\u003cUSER\u003e/cpptypes.svg?branch=main)](https://cirrus-ci.com/github/\u003cUSER\u003e/cpptypes)\n[![ReadTheDocs](https://readthedocs.org/projects/cpptypes/badge/?version=latest)](https://cpptypes.readthedocs.io/en/stable/)\n[![Coveralls](https://img.shields.io/coveralls/github/\u003cUSER\u003e/cpptypes/main.svg)](https://coveralls.io/r/\u003cUSER\u003e/cpptypes)\n[![Conda-Forge](https://img.shields.io/conda/vn/conda-forge/cpptypes.svg)](https://anaconda.org/conda-forge/cpptypes)\n[![Monthly Downloads](https://pepy.tech/badge/cpptypes/month)](https://pepy.tech/project/cpptypes)\n[![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social\u0026label=Twitter)](https://twitter.com/cpptypes)\n--\u003e\n\n[![Project generated with PyScaffold](https://img.shields.io/badge/-PyScaffold-005CA0?logo=pyscaffold)](https://pyscaffold.org/)\n[![PyPI-Server](https://img.shields.io/pypi/v/cpptypes.svg)](https://pypi.org/project/cpptypes/)\n![Unit tests](https://github.com/BiocPy/cpptypes/actions/workflows/pypi-test.yml/badge.svg)\n\n\n# Generate ctypes wrappers\n\n## Overview\n\nThis script automatically creates the C++ and Python-side wrappers for **ctypes** bindings.\nSpecifically, we fill `restype` and `argtypes` based on the C++ function signature and we create wrappers to handle C++ exceptions.\nWe were inspired by the `Rcpp::compile()` function, which does the same for C++ code in R packages.\nThe aim is to avoid errors from manual binding when developing **ctypes**-based Python packages.\n\n## Install\n\n**cpptypes** is published to [PyPI](https://pypi.org/project/cpptypes/):\n\n```sh\npip install cpptypes\n```\n\n## Quick start\n\nTo use, add an `// [[export]]` tag above the C++ function to be exported to Python.\n\n```cpp\n// [[export]]\nint multiply(int a, double b) {\n    return a * b;\n}\n```\n\nWe assume that all C++ code is located within a single directory `src`.\nWe then run the [`cpptypes`](./src/cpptypes/__main__.py) cli provided by this package:\n\n```sh\ncpptypes src/ --py bindings.py --cpp bindings.cpp\n```\n\nDevelopers should add `bindings.cpp` to the `Extension` sources in their `setup.py`.\nThe exported function itself can then be used in Python code with:\n\n```py\nfrom .bindings import * as cxx\n\ncxx.multiply(1, 2)\n```\n\n## Handling pointers\n\nPointers to base types (or `void`) are supported and will be bound with the appropriate **ctypes** pointer type.\n\n```cpp\n//[[export]]\nvoid* create_complex_object(int* my_int, double* my_dbl) {\n    return reinterpret_cast\u003cvoid*\u003e(new Something(my_int, my_dbl));\n}\n```\n\nAnd then, in Python (assuming we called our Python bindings file `bindings.py`):\n\n```py\nimport ctypes \nx = ctypes.c_int(100)\ny = ctypes.c_double(200)\n\nfrom .bindings import * as cxx\nptr = cxx.create_complex_object(ctypes.byref(x), ctypes.pointer(y))\n```\n\nVoid pointers are represented as a (usually 64-bit) integer in Python that can be passed back to C++.\nRemember to cast `void*` back to the appropriate type before doing stuff with it!\n(For simplicity, we do not support arbitrary pointer types as otherwise we would need to include the header definitions in the `bindings.cpp` file and that would be tedious to track.)\n\nIf you want the **ctypes** bindings to treat pointers to base types as `void*`, you can tag the argument with `void_p`.\nThis means that you can directly pass integer addresses to `my_int` and `my_dbl` in Python rather than casting them to a `ctypes.POINTER` type.\n\n```cpp\n//[[export]]\nvoid* create_complex_object2(int* my_int /** void_p */, double* my_dbl /** void_p */) {\n    return reinterpret_cast\u003cvoid*\u003e(new Something(my_int, my_dbl));\n}\n```\n\n**Note on tags:**\nArguments can be tagged with a `/** xxx yyy zzz */` comment, consisting of space-separated tags that determine how the type should be handled in the wrappers.\n(The double `**` is important to distinguish from non-tag comments.)\nThe tag-containing comment can be inserted anywhere in or next to the argument, e.g., before the type, between the type and the name, after the name but before the comma/parenthesis.\nThe result type for the function can also be tagged in the same manner.\n\n## Handling NumPy arrays\n\nIf we know a certain pointer is derived from a NumPy array, we can add the `numpy` tag to automate type checking and address extraction.\n\n```cpp\n//[[export]]\nvoid* create_complex_object3(int32_t* my_int /** numpy */, double* my_dbl /** numpy */) {\n    return reinterpret_cast\u003cvoid*\u003e(new Something(my_int, my_dbl));\n}\n```\n\nThen, in Python, we can just pass the arrays directly to the bound function:\n\n```py\nimport numpy\nx = numpy.random.rand(1000).astype(numpy.int32)\ny = numpy.random.rand(1000).astype(numpy.double)\ncxx.create_complex_object3(x, y)\n```\n\nThis will check that the NumPy arrays correspond to the specified type before calling the C++ function.\nIt is best to use fixed-width integers rather than relying on machine-dependent aliases like `int`, `short`, etc.\n\nThe wrapper functions will also check that the arrays are contiguous in memory.\nIf you want to support non-contiguous arrays, add the `non_contig` tag to the relevant arguments.\n\nThe `numpy` tag is only relevant to function arguments and not return values.\nUse the `numpy.ctypeslib.as_array()` function to convert a **ctypes** pointer to a **numpy** array of the relevant type.\n\n## Known limitations\n\n- Not all **ctypes** types are actually supported, mostly out of laziness.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiocpy%2Fcpptypes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbiocpy%2Fcpptypes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiocpy%2Fcpptypes/lists"}