I'm wrapping a C API that uses the typical fake-OOP idiom of opaque reference
types as "classes". In this case they're ref-counted. For example:
typedef struct Box Box;
Box* box_new(int size);
void box_release(Box*);
void box_retain(Box*);
int box_get_size(const Box*);
Run
I can easily create a Nim API for this, by hand or by using c2nim, and it's
pretty friendly to use, except that now the Nim programmer is responsible for
memory management, balancing every box_new with box_release. Not good.
I dug around and found the "Nim Destructors And Move Semantics" document, which
describes the `=destroy` and `=` hook functions. So now I've made an object
type that holds a C pointer, with a destructor and a copier.
type NimBoxObj = object
handle: ptr Box
type NimBox = ref NimBoxObj
proc `=destroy`(b: var NimBoxObj) = release(b.handle)
proc newBox(size: int): NimBox = NimBox(handle: box_new(size))
Run
I'm just wondering if this is the best approach. It's got a few flaws:
* Another heap allocation for each C object
* I have to redeclare the entire API (minus retain/release) for my new NimBox
type
I thought of doing this without the refs — just use NimBoxObj directly — making
it more like a C++ smart pointer type. But that means NimBoxObj instances will
get copied a lot during assignments and function calls, doesn't it? I'm
concerned that the consequent calls to `box_retain` and `box_release` might be
performance issues. Or am I making too much of this?
Ideally there'd be a way to avoid wrapping the C type in an object, but I
suspect that won't work because it's a `ptr` and that does explicitly mean
_[unmanaged](https://forum.nim-lang.org/postActivity.xml#unmanaged).
Any suggestions? Or pointers [sic] to existing libraries that do a good job of
this?