Easy way to create portable bindings to opaque C types

Have you ever struggled to create bindings for C types like FILE or CURL? If yes, then you know how hard it can be, since the type might not be same on all platforms.

Easy solution for these is to define a null record which represents the type and use only access types (pointers) when handling the type.

For example

type CURL_Type is null record;
type CURL_Access is access all CURL_Type;

function curl_easy_init return CURL_Access;
pragma Import (C, curl_easy_init, "curl_easy_init");

CURL_Obj : CURL_Access;
CURL_Obj := curl_easy_init;

This works on all platforms, all compilers, and all relatively recent Ada variants (95, 2005, 2012 at least).

Of course, if you need to change the internals of the C variables from Ada, this approach does not work.