{"id":13455190,"url":"https://github.com/Geode-solutions/genepi","last_synced_at":"2025-03-24T08:31:37.686Z","repository":{"id":35141415,"uuid":"212115949","full_name":"Geode-solutions/genepi","owner":"Geode-solutions","description":"Automatic generation of N-API wrapper from a C++ library","archived":false,"fork":false,"pushed_at":"2023-07-12T03:07:30.000Z","size":208,"stargazers_count":80,"open_issues_count":11,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-01T13:21:22.219Z","etag":null,"topics":["bindings","cmake","n-api","napi","node-addon-api","nodejs","wrapper"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@geode/genepi","language":"C++","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/Geode-solutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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":null}},"created_at":"2019-10-01T14:22:03.000Z","updated_at":"2024-08-07T19:04:03.000Z","dependencies_parsed_at":"2024-01-12T01:14:54.287Z","dependency_job_id":"9b60381d-3ca6-4b39-94d9-0ca0fe571897","html_url":"https://github.com/Geode-solutions/genepi","commit_stats":{"total_commits":29,"total_committers":5,"mean_commits":5.8,"dds":0.6206896551724138,"last_synced_commit":"9262f6eaea0c440a4e18a3eeb5f2ae429ed7aef8"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geode-solutions%2Fgenepi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geode-solutions%2Fgenepi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geode-solutions%2Fgenepi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geode-solutions%2Fgenepi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Geode-solutions","download_url":"https://codeload.github.com/Geode-solutions/genepi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221947441,"owners_count":16906128,"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","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":["bindings","cmake","n-api","napi","node-addon-api","nodejs","wrapper"],"created_at":"2024-07-31T08:01:02.252Z","updated_at":"2024-10-28T22:30:38.192Z","avatar_url":"https://github.com/Geode-solutions.png","language":"C++","readme":"\u003ch1 align=\"center\"\u003eGenepi\u003csup\u003e\u003ci\u003eby Geode-solutions\u003c/i\u003e\u003c/sup\u003e\u003c/h1\u003e\n\u003ch3 align=\"center\"\u003eAutomatic generation of N-API wrapper from a C++ library\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/Geode-solutions/genepi/workflows/CI/badge.svg\" alt=\"Build Status\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/release/Geode-solutions/genepi.svg\" alt=\"Version\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/static/v1?label=Windows\u0026logo=windows\u0026logoColor=white\u0026message=support\u0026color=success\" alt=\"Windows support\"\u003e\n  \u003cimg src=\"https://img.shields.io/static/v1?label=Linux\u0026logo=linux\u0026logoColor=white\u0026message=support\u0026color=success\" alt=\"Linux support\"\u003e\n  \u003cimg src=\"https://img.shields.io/static/v1?label=macOS\u0026logo=apple\u0026logoColor=white\u0026message=support\u0026color=success\" alt=\"macOS support\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/C%2B%2B-11-blue.svg\" alt=\"Language\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg\" alt=\"Semantic-release\"\u003e\n  \u003ca href=\"https://slackin-opengeode.herokuapp.com\"\u003e\u003cimg src=\"https://slackin-opengeode.herokuapp.com/badge.svg\" alt=\"Slack invite\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Introduction\n`genepi` is a C++11 library providing a complete set of macros to generate a Node.js addon from your C++ code using N-API. \n\n`genepi` works with [cmake-js](https://github.com/cmake-js/cmake-js) (a Node.js native addon of [CMake](https://cmake.org/)) as build system. CMake is largely used in the C++ community, here are some arguments to why CMake is a great build system for Node.js addons: [link](https://github.com/cmake-js/cmake-js#why-cmake).\n\n`genepi` is **MIT licensed** and based on templates and macros inspired by [nbind](https://github.com/charto/nbind) but using N-API.\n\n## Features\n`genepi` allows you to:\n\n- Use your C++ API from JavaScript without any extra effort.\n  - From **Node.js** and **Electron**,\n  - On Linux, macOS and Windows,\n  - Without changes to your C++ code. Simply add a separate short description at the end.\n- Distribute **native** code binary.\n\nIn more detail:\n\n- Export C++ classes, even ones not visible from other files.\n- Export multiple C++ inheritances, even between several libraries.\n- Export C++ methods simply by mentioning their names.\n- Auto-detect argument and return types from C++ declarations.\n- [Automatically convert types](#type-conversion) and data structures between languages.\n- Call C++ methods from JavaScript with type checking.\n- Pass instances of compatible classes by value between languages (through the C++ stack).\n\n## Requirements\nYou need [Node.js](https://nodejs.org/) (at least v10.x) and one of the following C++ compilers:\n\n- GCC 4.8 or above,\n- Clang 3.6 or above,\n- Visual Studio 2015 ([the Community version](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx) is fine).\n\n## Quick start\n1. Use your already existing C++ code in JavaScript\n\n```C++\n// My C++ code in hello.cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n \nstruct Greeter {\n    static void sayHello( const std::string\u0026 name ) \n    {\n        std::cout \u003c\u003c \"Hello, \" \u003c\u003c name \u003c\u003c std::endl;\n    }\n};\n```\n\n2. Install genepi and add some scripts to the `package.json`\n```Shell\nnpm install @geode/genepi\n```\n\n```JSON\n{\n  \"scripts\": {\n    \"build\": \"cmake-js compile\",\n    \"build:debug\": \"cmake-js compile -D\"\n  }\n}\n```\n\n3. Add JavaScript binding\n\n```C++\n// Add this to the file (or in another file)\n#include \u003cgenepi/genepi.h\u003e\n \nGENEPI_CLASS( Greeter )\n{\n    GENEPI_METHOD( sayHello );\n}\nGENEPI_MODULE( hello )\n```\n\n4. Configure your project by creating a `CMakeLists.txt`\n```CMake\ncmake_minimum_required(VERSION 3.5)\n\nproject(my_project)\n\nfind_package(genepi REQUIRED PATHS ${PROJECT_SOURCE_DIR}/node_modules/@geode/genepi/build)\n\nadd_genepi_library(my_project \"hello.cpp\")\n```\n\n5. Compile your addon\n```Shell\nnpm run build\n```\n\n6. Use it!\n```JavaScript\nvar myProject = require('my_project.node');\nmyProject.Greeter.sayHello('you');\n```\n\n## User guide\n- [Creating your project](#creating-your-project)\n- [Calling from Node.js](#calling-from-nodejs)\n- [Functions](#functions)\n- [Overloaded functions](#overloaded-functions)\n- [Classes and constructors](#classes-and-constructors)\n- [Methods](#methods)\n- [Overloaded methods](#overloaded-methods)\n- [Inheritance](#inheritance)\n- [Passing data structures](#passing-data-structures)\n- [Using objects](#using-objects)\n- [Type conversion](#type-conversion)\n\n### Creating your project\nCreate your repository using the provided Github template: [genepi-template](https://github.com/Geode-solutions/genepi-template).\nHere is how to use a Github template: [link](https://help.github.com/en/articles/creating-a-repository-from-a-template).\n\n### Calling from Node.js\nEach `genepi` module (i.e. each Node.js addon generated) needs to be registered using the `GENEPI_MODULE` macro:\n\n```C++\n// My C++ library\n\nGENEPI_MODULE( my_addon );\n```\n\nThis name `my_addon` is only used by [N-API](https://nodejs.org/api/n-api.html#n_api_module_registration).\nThe name of the addon is set in the `CMakeLists.txt` using the `add_genepi_library` macro. See [Quick start](#quick-start).\n\n```JavaScript\n// My JavaScript file\nvar example = require('my-genepi-addon.node');\n\n// Use the binding\n```\n\nThis `require` will only work if the module can be found by Node.js. To ease the import, you can use the package [bindings](https://www.npmjs.com/package/bindings). It will try several possible paths to find the module.\n\n```JavaScript\n// My JavaScript file\nvar example = require('bindings')('my-genepi-addon');\n\n// Use the binding\n```\n\n\n### Functions\nFunctions not belonging to any class can be exported inside a named or an anonymous namespace.\nThe C++ function gets exported to JavaScript with the same name using `GENEPI_FUNCTION`,\nor it can be renamed by adding a second argument (without quotation marks) using `NAMED_GENEPI_FUNCTION`.\nAddind double underscore in the new name will result in adding the function in nested objects on the js side.\n\nIf the C++ function is overloaded, `GENEPI_MULTIFUNCTION` macro must be used\ninstead. See [overloaded functions](#overloaded-functions).\n\nExample from C++: **[`functions.cpp`](https://github.com/Geode-solutions/genepi/blob/master/examples/functions/functions.cpp)**\n\n```C++\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\nvoid sayHello( const std::string\u0026 name )\n{\n    std::cout \u003c\u003c \"Hello, \" \u003c\u003c name \u003c\u003c std::endl;\n}\n\nvoid sayBye( const std::string\u0026 name )\n{\n    std::cout \u003c\u003c \"Bye, \" \u003c\u003c name \u003c\u003c std::endl;\n}\n\nvoid sayByeAgain( const std::string\u0026 name )\n{\n    std::cout \u003c\u003c \"Bye again, \" \u003c\u003c name \u003c\u003c std::endl;\n}\n\nnamespace foo\n{\n    void sayNamespacedHello( const std::string\u0026 name )\n    {\n        std::cout \u003c\u003c \"Hello, \" \u003c\u003c name \u003c\u003c std::endl;\n    }\n}\n\n#include \u003cgenepi/genepi.h\u003e\n\nnamespace\n{\n    GENEPI_FUNCTION( sayHello );\n    NAMED_GENEPI_FUNCTION( sayBye, sayGoodbye );\n    NAMED_GENEPI_FUNCTION( sayByeAgain, say__Goodbye );\n}\n\nnamespace foo\n{\n    GENEPI_FUNCTION( sayNamespacedHello );\n}\n\nGENEPI_MODULE( functions );\n```\n\nExample from JavaScript: **[`functions.js`](https://github.com/Geode-solutions/genepi/blob/master/examples/functions/functions.js)**\n\n```JavaScript\nvar functions = require('genepi-functions.node');\n\nfunctions.sayHello('you'); // Output: Hello, you\nfunctions.sayGoodbye('you'); // Output: Bye, you\nfunctions.say.Goodbye('you'); // Output: Bye again, you\nfunctions.sayNamespacedHello('you'); // Output: Hello, you\n```\n\n### Overloaded functions\nThe `GENEPI_FUNCTION()` macro cannot distinguish between several\noverloaded versions of the same function, causing an error.\nIn this case the `GENEPI_MULTIFUNCTION()` macro must be used.\n\nThe second parameter of the macro is the return type.\nFor calling from JavaScript, each overload needs to have a distinct name, given in the third parameter (without quotation marks).\nThe remaining parameters are the parameter types of the C++ function.\n\nExample from C++: **[`overloaded-functions.cpp`](https://github.com/Geode-solutions/genepi/blob/master/examples/overloaded-functions/overloaded-functions.cpp)**\n\n```C++\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\nvoid test( const std::string\u0026 number )\n{\n    std::cout \u003c\u003c \"Number \" \u003c\u003c number \u003c\u003c std::endl;\n}\n\nvoid test( int number )\n{\n    std::cout \u003c\u003c \"Number \" \u003c\u003c number \u003c\u003c std::endl;\n}\n\nvoid test( int number, int another_number )\n{\n    std::cout \u003c\u003c \"Number \" \u003c\u003c number + another_number \u003c\u003c std::endl;\n}\n\n#include \u003cgenepi/genepi.h\u003e\n\nnamespace\n{\n    GENEPI_MULTIFUNCTION( test, void, test_string, const std::string\u0026 );\n    GENEPI_MULTIFUNCTION( test, void, test_int, int );\n    GENEPI_MULTIFUNCTION( test, void, test_int2, int, int );\n}\n\nGENEPI_MODULE( overloaded_functions );\n```\n\nExample from JavaScript: **[`overloaded-functions.js`](https://github.com/Geode-solutions/genepi/blob/master/examples/overloaded-functions/overloaded-functions.js)**\n\n```JavaScript\nvar overloadedFunctions = require('genepi-overloaded-functions.node');\n\noverloadedFunctions.test_string('42'); // Output: Number 42\noverloadedFunctions.test_int(42); // Output: Number 42\noverloadedFunctions.test_int2(20, 22); // Output: Number 42\n```\n\n### Classes and constructors\nThe `GENEPI_CLASS(className)` macro takes the name of your C++ class as an argument\n(without any quotation marks), and exports it to JavaScript using the same name.\nIt's followed by a curly brace enclosed block of method exports,\nas if it was a function definition.\n\nThe class can be renamed on the JavaScript side by using the `NAMED_GENEPI_CLASS` macro and passing a string as a\nsecond argument. This is especially useful for binding a template class\nspecialization with a more reasonable name: `NAMED_GENEPI_CLASS(Data\u003cint\u003e, IntData)`.\n\nConstructors are exported with a macro call `GENEPI_CONSTRUCTOR(types...);` where `types` is a comma-separated list of arguments to the constructor, such as `int, int`. Calling `GENEPI_CONSTRUCTOR` multiple times allows overloading it.\n\nConstructor arguments are the only types that `genepi` cannot detect automatically.\n\nExample from C++: **[`classes.cpp`](https://github.com/Geode-solutions/genepi/blob/master/examples/classes/classes.cpp)**\n\n```C++\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\nclass ClassExample\n{\npublic:\n    ClassExample()\n    {\n        std::cout \u003c\u003c \"No arguments\" \u003c\u003c std::endl;\n    }\n\n    ClassExample( int a, int b )\n    {\n        std::cout \u003c\u003c \"Ints: \" \u003c\u003c a \u003c\u003c \" \" \u003c\u003c b \u003c\u003c std::endl;\n    }\n\n    ClassExample( const std::string\u0026 msg )\n    {\n        std::cout \u003c\u003c \"String: \" \u003c\u003c msg \u003c\u003c std::endl;\n    }\n};\n\n#include \u003cgenepi/genepi.h\u003e\n\nGENEPI_CLASS( ClassExample )\n{\n    GENEPI_CONSTRUCTOR();\n    GENEPI_CONSTRUCTOR( int, int );\n    GENEPI_CONSTRUCTOR( const std::string\u0026 );\n}\n\nGENEPI_MODULE( classes );\n```\n\nExample from JavaScript: **[`classes.js`](https://github.com/Geode-solutions/genepi/blob/master/examples/classes/classes.js)**\n\n```JavaScript\nvar classes = require('genepi-classes.node');\n\nvar a = new classes.ClassExample();  // Output: No arguments\nvar b = new classes.ClassExample(42, 54); // Output: Ints: 42 54\nvar c = new classes.ClassExample(\"Don't panic\"); // Output: String: Don't panic\n```\n\n### Methods\nMethods are exported inside a `GENEPI_CLASS` or a `NAMED_GENEPI_CLASS` block with a macro call `GENEPI_METHOD`\nwhich takes the name of the method as an argument (without any quotation marks).\nThe C++ method gets exported to JavaScript with the same name.\n\nIf the C++ method is overloaded, `GENEPI_MULTIMETHOD` macro must be used instead.\nSee [overloaded methods](#overloaded-methods).\n\nIf the method is `static`, it becomes a property of the JavaScript constructor function\nand can be accessed like `className.methodName()`. Otherwise it becomes a property of\nthe prototype and can be accessed like `obj = new className(); obj.methodName();`\n\nExample from C++: **[`methods.cpp`](https://github.com/Geode-solutions/genepi/blob/master/examples/methods/methods.cpp)**\n\n```C++\n#include \u003ciostream\u003e\n\nclass MethodExample\n{\npublic:\n    void add( int a, int b )\n    {\n        sum_ += a + b;\n        std::cout \u003c\u003c \"Sum = \" \u003c\u003c sum_ \u003c\u003c std::endl;\n    }\n\n    static void static_add( int a, int b )\n    {\n        MethodExample example;\n        example.add( a, b );\n    }\n\nprivate:\n    int sum_{ 0 };\n};\n\n#include \u003cgenepi/genepi.h\u003e\n\nGENEPI_CLASS( MethodExample )\n{\n    GENEPI_CONSTRUCTOR();\n    GENEPI_METHOD( add );\n    GENEPI_METHOD( static_add );\n}\n\nGENEPI_MODULE( methods );\n```\n\nExample from JavaScript: **[`methods.js`](https://github.com/Geode-solutions/genepi/blob/master/examples/methods/methods.js)**\n\n```JavaScript\n\nvar methods = require('genepi-methods.node');\n\nvar example = new methods.MethodExample();\nexample.add(12, 24); // Output: Sum = 36\n\nmethods.MethodExample.static_add(12,24); // Output: Sum = 36\n\n```\n### Overloaded methods\nThe `GENEPI_METHOD()` macro, like `GENEPI_FUNCTION` macro, cannot distinguish between several\noverloaded versions of the same method.\nIn this case the `GENEPI_MULTIMETHOD()` macro must be used.\n\nThe second parameter of the macro is the return type.\nFor calling from JavaScript, each overload needs to have a distinct name, given in the third parameter **(WITH quotation marks)**.\nThe remaining parameters are the parameter types of the C++ method.\n\nExample from C++: **[`overloaded-methods.cpp`](https://github.com/Geode-solutions/genepi/blob/master/examples/overloaded-methods/overloaded-methods.cpp)**\n\n```C++\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\nclass OverloadMethod\n{\npublic:\n    void test( const std::string\u0026 number )\n    {\n        std::cout \u003c\u003c \"Number \" \u003c\u003c number \u003c\u003c std::endl;\n    }\n\n    void test( int number )\n    {\n        std::cout \u003c\u003c \"Number \" \u003c\u003c number \u003c\u003c std::endl;\n    }\n\n    void test( int number, int another_number )\n    {\n        std::cout \u003c\u003c \"Number \" \u003c\u003c number + another_number \u003c\u003c std::endl;\n    }\n};\n\n#include \u003cgenepi/genepi.h\u003e\n\nGENEPI_CLASS( OverloadMethod )\n{\n    GENEPI_CONSTRUCTOR();\n    GENEPI_MULTIMETHOD( test, void, \"test_string\", const std::string\u0026 );\n    GENEPI_MULTIMETHOD( test, void, \"test_int\", int );\n    GENEPI_MULTIMETHOD( test, void, \"test_int2\", int, int );\n}\n\nGENEPI_MODULE( overloaded_methods );\n```\n\nExample from JavaScript: **[`overloaded-functions.js`](https://github.com/Geode-solutions/genepi/blob/master/examples/overloaded-functions/overloaded-functions.js)**\n\n```JavaScript\nvar overloadedMethods = require('genepi-overloaded-methods.node');\n\nvar a = new overloadedMethods.OverloadMethod();\na.test_string('42'); // Ouput: Number 42\na.test_int(42); // Ouput: Number 42\na.test_int2(20, 22); // Ouput: Number 42\n```\n\n### Inheritance\nWhen a C++ class inherits another, the `GENEPI_INHERIT` macro can be used to allow calling parent\nclass methods on the child class, or passing child class instances to C++ methods expecting\nparent class instances.\n\nInternally JavaScript only has prototype-based single inheritance while C++ supports\nmultiple inheritance. To simulate it, `genepi` will copy the contents of the parents to the prototype. This has otherwise\nthe same effect, except the JavaScript `instanceof` operator will return `false` for the parent classes.\n\nExample from C++: **[`inherit.cpp`](https://github.com/Geode-solutions/genepi/blob/master/examples/inherit/inherit.cpp)**\n\n```C++\n#include \u003ciostream\u003e\n\nclass FirstParent\n{\npublic:\n    FirstParent()\n    {\n        std::cout \u003c\u003c \"FirstParent\" \u003c\u003c std::endl;\n    }\n\n    void from_first_parent()\n    {\n        std::cout \u003c\u003c \"from first parent\" \u003c\u003c std::endl;\n    }\n};\n\nclass SecondParent\n{\npublic:\n    SecondParent()\n    {\n        std::cout \u003c\u003c \"SecondParent\" \u003c\u003c std::endl;\n    }\n\n    void from_second_parent()\n    {\n        std::cout \u003c\u003c \"from second parent\" \u003c\u003c std::endl;\n    }\n};\n\nclass Child: public FirstParent, public SecondParent\n{\npublic:\n    Child()\n    {\n        std::cout \u003c\u003c \"Child\" \u003c\u003c std::endl;\n    }\n};\n\n#include \u003cgenepi/genepi.h\u003e\n\nGENEPI_CLASS( FirstParent )\n{\n    GENEPI_CONSTRUCTOR();\n    GENEPI_METHOD( from_first_parent );\n}\n\nGENEPI_CLASS( SecondParent )\n{\n    GENEPI_CONSTRUCTOR();\n    GENEPI_METHOD( from_second_parent );\n}\n\nGENEPI_CLASS( Child )\n{\n    GENEPI_CONSTRUCTOR();\n    GENEPI_INHERIT( FirstParent );\n    GENEPI_INHERIT( SecondParent );\n}\n\nGENEPI_MODULE( inherit );\n```\n\nExample from JavaScript: **[`overloaded-methods.js`](https://github.com/Geode-solutions/genepi/blob/master/examples/overloaded-methods/overloaded-methods.js)**\n\n```JavaScript\nvar inherit = require('genepi-inherit.node');\n\nvar a = new inherit.Child(); // Ouput: FirstParent / SecondParent / Child\na.from_first_parent(); // Output: from first parent\na.from_second_parent(); // Output: from second parent\n```\n\n### Passing data structures\n`genepi` supports automatically converting between JavaScript arrays and C++\n`std::vector` or `std::array` types. Just use them as arguments or return values\nin C++ methods.\n\nNote that data structures don't use the same memory layout in both languages,\nso the data always gets copied which takes more time for more data.\nFor example the strings in an array of strings also get copied,\none character at a time.\n\n### Using objects\nC++ objects can be passed to and from JavaScript using different\nparameter and return types in C++ code:\n\n- *by reference* using pointers or references\n- *by value*\n\nConstness of objects is **not** ensured by `genepi`. So you could call a non const method on a const object.\n\nNote: using pointers and references is particularly **dangerous** because the pointer may become invalid without JavaScript noticing it.\n\nExample from C++: **[`objects.cpp`](https://github.com/Geode-solutions/genepi/blob/master/examples/objects/objects.cpp)**\n\n```C++\n#include \u003ciostream\u003e\n\nclass Coord\n{\npublic:\n    Coord( int x, int y ) : x_( x ), y_( y ) {}\n\n    int getX()\n    {\n        return x_;\n    }\n    int getY()\n    {\n        return y_;\n    }\n\nprivate:\n    int x_, y_;\n};\n\nclass ObjectExample\n{\npublic:\n    static void showByValue( Coord coord )\n    {\n        std::cout \u003c\u003c \"C++ value \" \u003c\u003c coord.getX() \u003c\u003c \", \" \u003c\u003c coord.getY()\n                  \u003c\u003c std::endl;\n    }\n\n    static void showByRef( Coord* coord )\n    {\n        std::cout \u003c\u003c \"C++ ref \" \u003c\u003c coord-\u003egetX() \u003c\u003c \", \" \u003c\u003c coord-\u003egetY()\n                  \u003c\u003c std::endl;\n    }\n\n    static Coord getValue()\n    {\n        return Coord{ 12, 34 };\n    }\n\n    static Coord* getRef()\n    {\n        static Coord coord{ 56, 78 };\n        return \u0026coord;\n    }\n};\n\n#include \u003cgenepi/genepi.h\u003e\n\nGENEPI_CLASS( Coord )\n{\n    GENEPI_CONSTRUCTOR( int, int );\n    GENEPI_METHOD( getX );\n    GENEPI_METHOD( getY );\n}\n\nGENEPI_CLASS( ObjectExample )\n{\n    GENEPI_METHOD( showByValue );\n    GENEPI_METHOD( showByRef );\n    GENEPI_METHOD( getValue );\n    GENEPI_METHOD( getRef );\n}\n\nGENEPI_MODULE( objects );\n```\n\nExample from JavaScript: **[`objects.js`](https://github.com/Geode-solutions/genepi/blob/master/examples/objects/objects.js)**\n\n```JavaScript\nvar objects = require('genepi-objects.node');\n\nvar value1 = new objects.Coord(123, 456);\nvar value2 = objects.ObjectExample.getValue();\nobjects.ObjectExample.showByValue(value1); // Output: C++ value 123, 456\nobjects.ObjectExample.showByValue(value2); // Output: C++ value 12, 34\n\nvar ref = objects.ObjectExample.getRef();\nobjects.ObjectExample.showByRef(ref); // Output: C++ ref 56, 78\n```\n\n### Type conversion\nParameters and return values of function calls between languages\nare automatically converted between equivalent types:\n\n| JavaScript | C++                                         |\n| ---------- | ------------------------------------------- |\n| number     | (`un`)`signed char`, `short`, `int`, `long` |\n| number     | `float`, `double`                           |\n| boolean    | `bool`                                      |\n| string     | `const` (`unsigned`) `char *`               |\n| string     | `std::string`                               |\n| Array      | `std::vector\u003ctype\u003e`                         |\n| Array      | `std::array\u003ctype, size\u003e`                    |\n| genepi-wrapped pointer | Pointer or reference to an instance of any bound class\u003cbr\u003eSee [Using objects](#using-objects) |\n\n## Alternatives\n- [nbind](https://github.com/charto/nbind)\n- [Embind](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html)\n- [v8pp](https://github.com/pmed/v8pp)\n\n\n## Questions\nFor questions and support please use the official [slack](https://slackin-opengeode.herokuapp.com) and go to the channel #genepi. The issue list of this repo is exclusively for bug reports and feature requests.\n\n\n## Changelog\nDetailed changes for each release are documented in the [release notes](https://github.com/Geode-solutions/OpenGeode/releases).\n\n\n## License\n\n[MIT](https://opensource.org/licenses/MIT)\n\nCopyright (c) 2019-present, Geode-solutions\n","funding_links":[],"categories":["Packages","包"],"sub_categories":["Miscellaneous","其他","杂项"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGeode-solutions%2Fgenepi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FGeode-solutions%2Fgenepi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGeode-solutions%2Fgenepi/lists"}