Gambas Documentation - /doc/extern

# External functions datatype mapping

This table depicts which Gambas datatype must be used in an extern function declaration according to its corresponding declaration in C.

C datatype | Gambas datatype
--- | ---
`char` | `Byte`
`bool` | `Boolean`
`short` | `Short`
`int` `long` (32 bits arch.) | `Integer`
`int64_t` `long` (64 bits arch.) | `Long`
`float` | `Single`
`double` | `Float`
`void *` | `pointer`
`char *` | `String` or `Pointer` See below.
`struct ABC *` | `ABC` or `STRUCT ABC` See below.

### Output arguments

When dealing with an argument in a C function, you must know (by reading the documentation or by being clever) if a pointer argument (`xxx *`) is actually an output argument or not.

If you see `const` at the beginning, the datatype is not an output argument, as that means the function will not modified it.

If you know that a function argument is an output argument:

1. You must declare it as a `pointer`.

2. You must declare a Gambas variable according to the datatype the argument points to: remove the last star, and look in the previous table.

3. When calling the function, pass the address of that variable using `VarPtr`.

Example:

    ' void get_device_name(void *device_id, char **name, int *len)
    ' This function gets a device id and returns its name.

    Extern get_device_name(device_id As Pointer, name As Pointer, len As Pointer)

    Dim name As Pointer ' actually a 'char *'
    Dim len As Integer

    get_device_name(device_id, VarPtr(name), VarPtr(len))

    Print "The name of the device is:";; String@(name, len))

### String arguments

In C, strings of characters are represented by the `char *` datatype or `const char *` datatype. It's a pointer that points at the string contents, and the end of the string is the first byte whose value is zero.

But a `char *` could just be a pointer to a byte. So you must be sure first, even if it is rare.

If an argument is a `const char *`, then you can declare it as a `String`.

Gambas will just pass a pointer to the beginning of the string. So you must ensure that the string is null-terminated.

This is the case if you don't use any function inside the call, i.e. if your string is store in some variable that you pass to the function.

If an argument is a `char *`, then maybe the function just wants a pointer to an allocation, and will fill it.

So you can declare the argument as a `pointer`. When calling the function you will allocate enough space with the `Alloc` function, and give the resulting pointer to the function.

Do not forget to call `Free` once the allocation is not needed anymore. Only you can know.

If an argument is a `char **`, the function will return a pointer to a string.

You can declare the argument as a `Pointer`, declare a variable `X As Pointer`, and pass its address to the function with `VarPtr(X)`. Then you will use `StrPtr(X)` to get the string pointed by `X`.

If the function returns a `char *`, you can declare the return value as a `String` or as a `Pointer`.

If you use `String`, then Gambas will return a copy of the pointed string. If you use `Pointer`, you will get the real returned string by using `StrPtr` on the returned pointer.

To know what to do, you must read the function documentation that must tell you the life duration of the memory pointed by the returned pointer.

### Structure arguments

A C structure can be declared in Gambas with the STRUCT instruction. Normally, any C structure can be mimicked in Gambas. See Structure declaration for more details.

There is no support for the `union` C declaration.

In C, a structure can be passed by value (the entire structure is put on the stack) or by reference (a pointer to the structure is sent).

As Gambas handles only the second case, so this may be an unsolvable problem if your function wants a structure passed by value.

If an argument is a `struct *ABC* *` or `const struct *ABC* *`, then you mimic the structure `ABC` declaration somewhere, and you declare the argument as `ABC`.

Gambas will pass a pointer to the structure data to the function.

If the function returns a `struct *ABC* *`, then you mimic the structure `ABC` declaration somewhere, and you declare the return value as `Struct ABC`.

Gambas will returns a structure whose takes its values directly from the pointer returned by the function. You won't get a copy!