Is there a Kotlin Native sample that shows how to ...
# kotlin-native
n
Is there a Kotlin Native sample that shows how to wrap a C Macro to create new instances (like a Struct for example) and manually free them later on?
n
Those examples provide some basic ideas, however I needed to find a solution that goes further where the contents of a C Macro are deep copied to a variable that is allocated on the heap. Haven't found a straightforward solution to this but have found a clunky workaround that involves deciphering the Macro and manually assigning values (includes manually setting up nested structs on the Kotlin side which is easier to deal with) to a variable that is allocated on the heap:
Copy code
static inline MQTTClient_connectOptions* createMqttConnectionOptions() {
    MQTTClient_connectOptions* options = (MQTTClient_connectOptions*) malloc(sizeof(MQTTClient_connectOptions));
    options->struct_id[0] = 'M';
    options->struct_id[1] = 'Q';
    options->struct_id[2] = 'T';
    options->struct_id[3] = 'C';
    options->struct_version = 6;
    options->reliable = 1;
    options->will = NULL;
    options->username = NULL;
    options->password = NULL;
    options->retryInterval = 0;
    options->ssl = NULL;
    options->serverURIcount = 0;
    options->serverURIs = NULL;
    options->MQTTVersion = MQTTVERSION_DEFAULT;
    options->maxInflightMessages = -1;
    return options;
}
Initialization of internal structs on the Kotlin side:
Copy code
// ...
private fun updateConnOptions(newConnOptions: MqttConnectionOptions, newUsername: CPointer<ByteVar>?,
                                  newPassword: CPointer<ByteVar>?) {
        setupConnOptionsReturned()
        setupConnOptionsBinarypwd()
        if (_connOptions != null) {
            with(_connOptions.pointed) {
                username = newUsername
                password = newPassword
                keepAliveInterval = newConnOptions.keepAliveInterval
                cleansession = if (newConnOptions.cleanSession) 1 else 0
                cleanstart = if (newConnOptions.cleanStart) 1 else 0
                connectTimeout = newConnOptions.connectionTimeout
                retryInterval = newConnOptions.retryInterval
            }
        }
    }

    private fun setupConnOptionsBinarypwd() {
        if (_connOptions != null) {
            with(_connOptions.pointed.binarypwd) {
                len = 0
                data = null
            }
        }
    }

    private fun setupConnOptionsReturned() {
        if (_connOptions != null) {
            with(_connOptions.pointed.returned) {
                serverURI = null
                sessionPresent = 0
                MQTTVersion = 0
            }
        }
    }