diff --git a/docs/bindings.md b/docs/bindings.md index 4ba92689..6a0f4309 100644 --- a/docs/bindings.md +++ b/docs/bindings.md @@ -17,6 +17,48 @@ typedef bool (*py_CFunction)(int argc, py_Ref argv); If successful, the function should return `true` and set the return value in `py_retval()`. In case there is no return value, you should use `py_newnone(py_retval())`. If an error occurs, the function should raise an exception and return `false`. +## Steps + +Say you have a function `add` that takes two integers and returns their sum. +```c +int add(int a, int b) { + return a + b; +} +``` + +Here is how you can write the binding for it: +```c +// 1. Define a wrapper function with the signature `py_CFunction`. +bool py_add(int argc, py_Ref argv) { + // 2. Check the number of arguments. + PY_CHECK_ARGC(2); + // 3. Check the type of arguments. + PY_CHECK_ARG_TYPE(0, tp_int); + PY_CHECK_ARG_TYPE(1, tp_int); + // 4. Convert the arguments into C types. + int _0 = py_toint(py_arg(0)); + int _1 = py_toint(py_arg(1)); + // 5. Call the original function. + int res = add(_0, _1); + // 6. Set the return value. + py_newint(py_retval(), res); + // 7. Return `true`. + return true; +} +``` + +Once you have the wrapper function, you can bind it to a python module via `py_bindfunc`. +```c +py_GlobalRef mod = py_getmodule("__main__"); +py_bindfunc(mod, "add", py_add); +``` + +Alternatively, you can use `py_bind` with a signature, which allows you to specify some default values. +```c +py_GlobalRef mod = py_getmodule("__main__"); +py_bind(mod, "add(a, b=1)", py_add); +``` + See also: + [`py_bind`](/c-api/functions/#py_bind) + [`py_bindmethod`](/c-api/functions/#py_bindmethod)