外部函数数据类型映射
此表描述了在外部函数声明中必须使用的Gambas数据类型根据其在C中的相应声明。
输出参数
当处理C函数中的一个参数时,您必须知道(通过阅读文档或机智对待)
指针参数('xxx*
)是否实际是输出参数。
如果你看到 const
在开始位置, 对应数据类型不是一个输出参数, 因为这意味着函数不会修改它。
如果你知道函数自变量是输出自变量:
-
你必须将它声明为
pointer
.
-
您必须根据参数指向的数据类型声明Gambas变量:删除最后一个星号,然后查找上表。
-
当调用该函数时,传递该变量使用的地址
VarPtr
.
示例:
' 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))
字符串参数
在 C 中, 字符串通过
char *
类型或
const char *
类型表示。
它是一个指向字符串内容的指针,字符串的末尾是第一个值为零的字节。
但是
char *
可以只是一个指向字节的指针。所以你必须先确定,即使这种情况很少见。
如果一个参数是 const char *
, 你可以将它定义为
String
.
Gambas只会将一个指针传递到字符串的开头。因此,您必须确保字符串以null结尾。
如果在调用中不使用任何函数,即字符串存储在传递给函数的某个变量中,就会出现这种情况。
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.
Wide-character string arguments
In C, wide-character strings are associated with the
wchar_t *
datatype. It represents a string, whose each character uses the same number of bytes.
You have now four problems:
-
The number of bytes is greater or equal than two, and system-dependent. It's normally four on Linux.
-
Consequently, the character encoding may be little or big endian.
-
The exact character set corresponding to
wchar_t *
is also system dependent.
-
The wide-character string is null terminated, but that null character is also multi-bytes. And Gambas only ensures one null byte at the end of strings.
To solve these problems, you have to:
-
Use the Conv$ function to convert your strings to the special
"WCHAR_T"
charset.
-
Add a null byte to the string before converting it:
Conv(MyString & Chr$(0), "UTF-8", "WCHAR_T")
That way, you will be sure that the string is null-terminated in the target character set.
Structure arguments
A C structure can be declared in Gambas with the
STRUCT instruction. Normally, any C structure can be mimicked in Gambas. See
结构体声明 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!