# Common Bindings Documentation ## What is this? Documentation for the usage of C# bindings generated by the minBND tool. If you're reading this you probably followed a link in the documentation of a C#/.NET library that uses minBND to generate code. Since the code will be similar in all of the libraries generated by minBND, we maintain the common documentation here. ## minBND Generated Bindings Overview minBND generates 100% GC-free bindings that are very minimal and readable. There is basic type handling by default and conversions between different typing profiles. The bindings should work reasonably well out of the box for any project, although they might not the the most efficient since minBND does not make heroic assumptions and counts on the user to configure it properly. The most important configuration is declaring the blittable types. If minBND cannot safely generate code, user interverion might be necessary. Types can always be blacklisted and handled manually by the user. minBND does not attempt to be the ultimate solution, it simply aims to automate what can be reasonably automated, what when properly done coud represent 100% of an API. ## Terminology This document uses specific terminology. While there's no consensus whether some of those terms are accurate or can be used interchangeably, we pay attention to stick to their meanins as follows: #### "Blittable" This simply means the memory layout/representation of the object is exactly the same on both sides, so they can simply be copied around. This does not imply in any other property of an object. Due to lack of ABI standardization, inheritance is a hard problem to solve and minBND is not guaranteed to generate code for blittables that is compatible with your ABI. Blitting objects in which data members are added throughout the inheritance is discouraged. #### "POD" Plain Old Data as specified and parsed by Clang. This basically means data-only objects. Default values (C++11 field def) do **not** mean the object isn't a POD, and due to lack of standardization there's room for discussion about differences between compilers. Normally this is referred to as a C++03 POD, although C++11 features affect Clang parser. #### "Returnable" The fact an object is blittable does **not** mean its value can be returned from native into managed code. The fact the object is a POD in theory should mean it's safe to return, but this is a complicated subject and minBND 5 onwards does not rely on the "returnability" of complex blittable types (non-primitives) in order to avoid potential problems. #### "Wrapper" This term does not necessarily mean there's interoperation and generally a "wrapper" code is written in the same language of the wrapped object. In a general contest, the term "Wrapper" is the C code that wraps the C/C++ objects and functions. #### "Binding" Binding is the managed code that interoperates with the native code through Pinvoke. These are exclusively managed code and might not include the Pinvoke code when there's a distiction (e.g. the Pinvokes can be generated in files separated from the Bindings). #### "Pinvoke" Also written P/Invoke (Platform Invoke), in this document written exclusively as "Pinvoke", is the actual language interoperation code. These are `extern` function declarations attributed with a `DllImport`. In a general context this could simply mean interoperation. ## Generated Types ### Primitives Primitives are value types that are available on both native and managed side, types like `float` and `int` are primitives. They are represented the same way on both sides. Please note that in the context of bindings, these don't necessarily map into the primitives of your language, a notable example is the `boolean` type for example which might need special handling/marshaling. Numeric types are normally consistent as long as their size match. ### Pointer Wrappers As the name suggests, these are managed objects that hold pointers to native memory. By default object that aren't blittable nor primitives are handled by pointer wrappers. On the managed side they are value types that work as typed pointers. The ##### Public Fields Managed getters and setters are automatically generated for all public fields in objects handled as pointer wrappers. These getters are bound as properties so they are acessed just like normal fields although under the hood they are Pinvoke calls to native code. ##### Newing and Freeing Pointer Wrappers can be newed with the static `New()` method and freed with the static or `Free(TPtr ptrWrapper)` method, or alternative with the non-static `Free()` method of the object. In most APIs you are required and responsible for freeing what you allocate after the object isn't necessary. So as a rule of thumb you'll want one `Free()` for each `New()` in your code. **IMPORTANT:** check [Value to Pointer Conversion] for possibly relevant information. ##### Value to Pointer Conversion When a given object is handled as a Pointer Wrapper in minBND, but objects of that type are returned by value in managed code, chances are the object should be handled as a Blittable. When that's not possible, instead of simply not binding that code, minBND will bind them with some special glue code that allocates memory and returns a pointer to those objects. That operation naturally requires you to manually free the returned pointers afterwards, and to make that clear all methods that allocate memory have a `_New` suffix, so you should manually free their returning objects after use. ##### Why not use the dispose pattern (IDisposable)? Implementing IDisposable would imply the object should be manually disposed, what depending on the API will almost never be the case. In any sane API you should only be responsible for freeing what you allocate, so you shouldn't be freeing objects from queries for example, and in many cases those objects might be the ones you've created (think spatial queries for example, like getting objects in some area). ### Blittable Types Blittable types are blitted (bits directly written to) back and forth between native and managed memory. By default all types that are not primitives are wrapped into pointers, but for some types like small PODs it's normally better to use bind them as blittables. Also, that makes it possible to operate directly on their memory data in the managed side, so for example instead of calling some unmanaged function to multiply two vectors, you can simply reproduce that operation in the managed side so there's no interoperation overhead. ##### Newing and Default Value Blittables are bound as `struct` objects and the constructor of the unmanaged object is called when you `new` them. However, unfortunately the default (parameterless) constructor isn't overridable, that means the memory of the object will always be zero when you call the default constructor, what might *not* be a valid initial state for the object in some very rare situations. To address that limitation, minBND implements the `Default()` static method on the blittable objects, this method calls the default managed constructor and returns the object from native. When you're not sure whether zeroing the memory is a valid initial state, it's good practice to call `MyBlittableType.Default()` instead of `new MyBlittableType()`. Please note that *only the default* constructor has this limitation, and even though, in the vast majority of cases, zeroed memory will be valid anyway. ##### Returning as Parameter Due to [limitations in interoperability](https://github.com/dotnet/coreclr/issues/23392), minBND doesn't return blittable objects directly from native calls, instead objects are passed into native as reference and the memory in the managed stack is blitted from native code. That way we ensure maximum compatibility while still allowing primitives and other safe types to be returned back directly from native for better debugging and readability of the pinvoke and wrapper code. Except for debugging and browsing code, none of that affects the normal usage of bindings in any way. ## General Usage Tips ### Overloads with Reference and Value parameters All functions/methods that take blittable types in minBND are primarily meant to operate on unsafe unmanaged references, internally minBND uses references as much as possible for maximum performance. That being said, all of these methods also have overloads that take values instead of references for conveniece reasons. However, if performance is critical you should preferably use the signatures that take unmanaged references, so for example instead of calling `someMethod(someBlittable)`, you should call `someMethod(&someBlittable)` (in unsafe context) which instead of copying the value simply passes a reference which is then handled directly as a reference without the potential overhead of copying the value. This is a micro-optimization and should affect performance *very* marginally though, or even not affect it at all. ## TODO memory management tips manual high-level API examples