cgo: implement rudimentary C array decaying

This is just a first step. It's not complete, but it gets some real
world C code to parse.

This signature, from the ESP-IDF:

    esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]);

Was previously converted to something like this (pseudocode):

    C.esp_err_t esp_wifi_get_mac(ifx C.wifi_interface_t, mac [6]uint8)

But this is not correct. C array parameters will decay. The array is
passed by reference instead of by value. Instead, this would be the
correct signature:

    C.esp_err_t esp_wifi_get_mac(ifx C.wifi_interface_t, mac *uint8)

So that it can be called like this (using CGo):

    var mac [6]byte
    errCode := C.esp_wifi_get_mac(C.ESP_IF_WIFI_AP, &mac[0])

This stores the result in the 6-element array mac.
This commit is contained in:
Ayke van Laethem
2021-09-24 03:05:10 +02:00
committed by Ron Evans
parent 04e8f44370
commit 5c0a337c4f
4 changed files with 50 additions and 1 deletions
+4
View File
@@ -61,3 +61,7 @@ void unionSetData(short f0, short f1, short f2) {
globalUnion.data[1] = 8;
globalUnion.data[2] = 1;
}
void arraydecay(int buf1[5], int buf2[3][8], int buf3[4][7][2]) {
// Do nothing.
}
+6
View File
@@ -128,6 +128,12 @@ func main() {
// Check whether CFLAGS are correctly passed on to compiled C files.
println("CFLAGS value:", C.cflagsConstant)
// Check array-to-pointer decaying. This signature:
// void arraydecay(int buf1[5], int buf2[3][8], int buf3[4][7][2]);
// decays to:
// void arraydecay(int *buf1, int *buf2[8], int *buf3[7][2]);
C.arraydecay((*C.int)(nil), (*[8]C.int)(nil), (*[7][2]C.int)(nil))
// libc: test whether C functions work at all.
buf1 := []byte("foobar\x00")
buf2 := make([]byte, len(buf1))
+4
View File
@@ -144,3 +144,7 @@ extern int cflagsConstant;
// test duplicate definitions
int add(int a, int b);
extern int global;
// Test array decaying into a pointer.
typedef int arraydecay_buf3[4][7][2];
void arraydecay(int buf1[5], int buf2[3][8], arraydecay_buf3 buf3);