mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 13:00:17 +00:00
...
This commit is contained in:
parent
3478ddeeb0
commit
5bbb534b20
@ -49,6 +49,65 @@ vm->bind(obj,
|
||||
});
|
||||
```
|
||||
|
||||
#### How to capture something
|
||||
|
||||
By default, the lambda being bound is a C function pointer,
|
||||
you cannot capture anything! The following example does not compile.
|
||||
|
||||
```cpp
|
||||
int x = 1;
|
||||
vm->bind(obj, "f() -> int", [x](VM* vm, ArgsView args){
|
||||
// error: cannot capture 'x'
|
||||
return py_var(vm, x);
|
||||
});
|
||||
```
|
||||
|
||||
I do not encourage you to capture something in a lambda being bound
|
||||
because:
|
||||
1. Captured lambda runs slower and causes "code-bloat".
|
||||
2. Captured values are unsafe, especially for `PyObject*` as they could leak by accident.
|
||||
|
||||
However, there are 3 ways to capture something when you really need to.
|
||||
The most safe and elegant way is to subclass `VM` and add a member variable.
|
||||
|
||||
```cpp
|
||||
class YourVM : public VM{
|
||||
public:
|
||||
int x;
|
||||
YourVM() : VM() {}
|
||||
};
|
||||
|
||||
int main(){
|
||||
YourVM* vm = new YourVM();
|
||||
vm->x = 1;
|
||||
vm->bind(obj, "f() -> int", [](VM* _vm, ArgsView args){
|
||||
// do a static_cast and you can get any extra members of YourVM
|
||||
YourVM* vm = static_cast<YourVM*>(_vm);
|
||||
return py_var(vm, vm->x);
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The 2nd way is to use `vm->bind`'s last parameter `userdata`, you can store a POD type smaller than 8 bytes.
|
||||
And use `lambda_get_userdata<T>(args.begin())` to get it inside the lambda body.
|
||||
|
||||
```cpp
|
||||
int x = 1;
|
||||
vm->bind(obj, "f() -> int", [](VM* vm, ArgsView args){
|
||||
// get the userdata
|
||||
int x = lambda_get_userdata<int>(args.begin());
|
||||
return py_var(vm, x);
|
||||
}, x); // capture x
|
||||
```
|
||||
|
||||
The 3rd way is to change the macro `PK_ENABLE_STD_FUNCTION` in `config.h`:
|
||||
```cpp
|
||||
#define PK_ENABLE_STD_FUNCTION 0 // => 1
|
||||
```
|
||||
|
||||
Then you can use standard capture list in lambda.
|
||||
|
||||
### Bind a struct
|
||||
|
||||
Assume you have a struct `Point` declared as follows.
|
||||
|
Loading…
x
Reference in New Issue
Block a user