royalapplications / beyondnet

A toolset that makes it possible to call .NET code from other programming languages, including C, Swift and Kotlin.
https://royalapps.com
MIT License
111 stars 5 forks source link

Memory Management #23

Closed lemonmojo closed 1 year ago

lemonmojo commented 1 year ago

While .NET's memory management model is based on Garbage Collection (GC), C uses manual memory management. That means, everything that is allocated on the heap must be manually freed to not cause a memory leak.

For the generated C bindings we adopt exactly that model.

There's practically only one rule regarding memory management: Every object received from .NET, no matter how it is obtained must be manually freed when not needed anymore.

The only exception to this rule are primitive types like integers, booleans, etc and enums. Those don't need to be freed.

The generator creates destructor methods for every exposed .NET type. For instance, the signature of the destructor for the System.Guid type looks like this: void System_Guid_Destroy(System_Guid_t self).

So if you, for instance obtain a reference to a System.Guid object by calling the generated binding for System.Guid.Empty you must at some point call the destructor, otherwise you're leaking memory.

Structs or other value types and delegates are no exception to this rule. Again, the only exception are primitive and enums. Also, it doesn't matter if you obtain an object by calling its constructor (*_Create functions in C) or through other means, you always have to destroy them at some point.

When using the generated bindings for Swift, there's no need to deal with any of that. Instead we handle allocation and deallocation transparently and the standard Swift memory management rules apply. That means you can just treat .NET objects like regular Swift objects. That includes .NET delegates which are mapped to Swift closures.