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?

Reply via email to