|
| 1 | +// NOTE: this assumes neuronapi.h is on your CPLUS_INCLUDE_PATH |
| 2 | +// Exercises nrn_object_ptr_push, which pushes a writable object-reference cell |
| 3 | +// (an Object**) rather than an object by value. This is the out-parameter form |
| 4 | +// behind the h.ref(obj) idiom: a callee that assigns to its $oN arg writes back |
| 5 | +// through the cell. nrn_object_push (by value) cannot express this. |
| 6 | +#include <array> |
| 7 | +#include <iostream> |
| 8 | +#include "neuronapi.h" |
| 9 | + |
| 10 | +using std::cerr; |
| 11 | +using std::endl; |
| 12 | + |
| 13 | +extern "C" void modl_reg(){/* No modl_reg */}; |
| 14 | + |
| 15 | +static bool check(bool cond, const char* msg) { |
| 16 | + if (!cond) { |
| 17 | + cerr << "FAIL: " << msg << endl; |
| 18 | + } |
| 19 | + return cond; |
| 20 | +} |
| 21 | + |
| 22 | +int main(void) { |
| 23 | + static std::array<const char*, 4> argv = {"object_ptr_push", "-nogui", "-nopython", nullptr}; |
| 24 | + nrn_init(3, argv.data()); |
| 25 | + |
| 26 | + bool ok = true; |
| 27 | + |
| 28 | + // A proc whose sole job is to write a fresh Vector back into its objref arg. |
| 29 | + nrn_hoc_call("proc make3() { $o1 = new Vector(3) }"); |
| 30 | + // And one that reads the passed object's size into the built-in hoc_ac_. |
| 31 | + nrn_hoc_call("proc readsize() { hoc_ac_ = $o1.size() }"); |
| 32 | + |
| 33 | + // Write-back: push the address of an empty cell, call make3, and confirm the |
| 34 | + // cell was populated. A by-value push could not update `slot` here. |
| 35 | + Object* slot = nullptr; |
| 36 | + nrn_object_ptr_push(&slot); |
| 37 | + nrn_function_call(nrn_symbol("make3"), 1); |
| 38 | + ok &= check(slot != nullptr, "objref cell was written back by the callee"); |
| 39 | + ok &= check(nrn_vector_capacity(slot) == 3, "written-back Vector has capacity 3"); |
| 40 | + |
| 41 | + // Read direction: push the now-populated cell and have HOC read $o1.size(). |
| 42 | + nrn_object_ptr_push(&slot); |
| 43 | + nrn_function_call(nrn_symbol("readsize"), 1); |
| 44 | + double* ac = nrn_symbol_dataptr(nrn_symbol("hoc_ac_")); |
| 45 | + ok &= check(ac != nullptr && *ac == 3.0, "HOC read the pushed object's size through the cell"); |
| 46 | + |
| 47 | + nrn_object_unref(slot); |
| 48 | + return ok ? 0 : 1; |
| 49 | +} |
0 commit comments