Kotlin / Native: как изменить CArrayPointer?

Я пытаюсь использовать K / N с libsecret. Он включает следующую структуру:

typedef struct {
    const gchar *name;
    SecretSchemaFlags flags;
    SecretSchemaAttribute attributes[32];
} SecretSchema;

(отсюда: https://developer.gnome.org/libsecret/0.18/libsecret-SecretSchema.html#SecretSchema)

cinterop сгенерировал следующий класс:

@kotlinx.cinterop.internal.CStruct public final class SecretSchema public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar {
   @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type {
   }

   public final val attributes: kotlinx.cinterop.CArrayPointer<org.libsecret.SecretSchemaAttribute> /* = kotlinx.cinterop.CPointer<org.libsecret.SecretSchemaAttribute> */ /* compiled code */

   public final var flags: org.libsecret.SecretSchemaFlags /* = kotlin.UInt */ /* compiled code */

   public final var name: kotlinx.cinterop.CPointer<org.libsecret.gcharVar /* = kotlinx.cinterop.ByteVarOf<kotlin.Byte> */>? /* compiled code */

   public final var reserved: org.libsecret.gint /* = kotlin.Int */ /* compiled code */

   public final var reserved1: org.libsecret.gpointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */

   public final var reserved2: org.libsecret.gpointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */

   public final var reserved3: org.libsecret.gpointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */

   public final var reserved4: org.libsecret.gpointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */

   public final var reserved5: org.libsecret.gpointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */

   public final var reserved6: org.libsecret.gpointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */

   public final var reserved7: org.libsecret.gpointer? /* = kotlinx.cinterop.CPointer<out kotlinx.cinterop.CPointed>? */ /* compiled code */
}

и я пытаюсь определить это так:

alloc<SecretSchema> {
   name = "com.charlag.tuta-bridge".cstr.ptr
   flags = SECRET_SCHEMA_NONE
}

однако я не вижу способа изменить attributes, потому что CArrayPointer (CPointer) не предоставляет методы модификации.

Я также заметил несколько полей reserved. Должен ли я использовать их вместо этого?

вот пример того, как он используется в C: https://developer.gnome.org/libsecret/0.18/c-examples.html#c-schema-example


person charlag    schedule 18.10.2020    source источник


Ответы (2)


Похоже, что по умолчанию нет способа, в итоге я сделал вот что:

/**
 * This is a version of the function which is missing in standard library. It initializes members
 * of the array.
 * If possible, allocate array of correct elements instead. It might not be possible with C
 * structures.
 */
inline fun <reified T : CVariable> CArrayPointer<T>.setAt(index: Int, value: CValue<T>) {
    value.write(this.rawValue + index * sizeOf<T>())
}

Он работает для меня и использует тот же расчет положения указателя, что и доступ

person charlag    schedule 20.10.2020

Насколько я понимаю, наиболее простым вариантом здесь было бы использовать оператор [] и назначить выделенный SecretSchemaAttribute этим адресам. Чтобы узнать больше о взаимодействии типов указателей, посетите эту страницу документации. . Возможно, он немного устарел, но дополнительные вопросы можно задать здесь или в kotlinlang Slack.

person Artyom Degtyarev    schedule 20.10.2020
comment
Это не работает, потому что нет set перегрузки для произвольных типов, только для примитивов. - person charlag; 20.10.2020