Veri türleri

HIDL veri beyanları, C++ standart düzen veri yapıları oluşturur. Bu yapılar doğal görünen herhangi bir yere (yığın üzerinde, dosyaya veya veya yığın halinde) aynı şekilde oluşturulabilir. Müşteri kod, const referanslarında ve temel türlerde ileten HIDL proxy kodunu çağırır. saplama ve proxy kodu da serileştirmenin ayrıntılarını gizler.

Not: Geliştirici tarafından yazılmış kod kesinlikle veri yapılarını açık bir şekilde serileştirmek veya seri durumdan çıkarmak için gereken tüm işlemler.

Aşağıdaki tabloda, temel HIDL öğeleri C++ veri türleriyle eşleştirilmektedir:

HIDL türü C++ Türü Başlık/kitaplık
enum enum class
uint8_t..uint64_t uint8_t..uint64_t <stdint.h>
int8_t..int64_t int8_t..int64_t <stdint.h>
float float
double double
vec<T> hidl_vec<T> libhidlbase
T[S1][S2]...[SN] T[S1][S2]...[SN]
string hidl_string libhidlbase
handle hidl_handle libhidlbase
safe_union (custom) struct
struct struct
union union
fmq_sync MQDescriptorSync libhidlbase
fmq_unsync MQDescriptorUnsync libhidlbase

Veri türleri aşağıdaki bölümlerde daha ayrıntılı olarak açıklanmaktadır.

numaralandırma

HIDL'deki bir numaralandırma, C++'ta bir enum haline gelir. Örnek:

enum Mode : uint8_t { WRITE = 1 << 0, READ = 1 << 1 };
enum SpecialMode : Mode { NONE = 0, COMPARE = 1 << 2 };

... şu hale gelir:

enum class Mode : uint8_t { WRITE = 1, READ = 2 };
enum class SpecialMode : uint8_t { WRITE = 1, READ = 2, NONE = 0, COMPARE = 4 };

Android 10'dan itibaren sıralama yinelenebilir ::android::hardware::hidl_enum_range kullanımından fazlası. Bu aralık her numaralandırıcıyı HIDL kaynak kodunda göründüğü sırayla içerir. alt kümeye doğru sıralar. Örneğin, bu kod yinelemeli WRITE, READ, NONE ve üzeri COMPARE bu sırada. Yukarıda verilen SpecialMode:

template <typename T>
using hidl_enum_range = ::android::hardware::hidl_enum_range<T>

for (SpecialMode mode : hidl_enum_range<SpecialMode>) {...}

hidl_enum_range, ters yinelemeler de uygular ve constexpr bağlamda kullanıldı. Numaralandırmada bir değer görünüyorsa birden çok kez tekrarlanırsa değer, aralıkta birden çok kez görünür.

bitfield<T>

bitfield<T> (burada T, kullanıcı tanımlı bir sıralamadır) C++ içindeki bu sıralamanın temel türü haline gelir. Yukarıdaki örnekte, bitfield<Mode>, uint8_t olur.

vec<T>

hidl_vec<T> sınıf şablonu şu grubun bir parçası: libhidlbase ve herhangi bir HIDL türündeki vektörü aktarmak için kullanılabilir. isteğe bağlıdır. Karşılaştırılabilir sabit boyutlu kapsayıcı, hidl_array hidl_vec<T>, kullanılarak T türünde harici bir veri arabelleğine işaret edilecek şekilde başlatıldı hidl_vec::setToExternal() işlevi.

Ayrıca, struct'ı oluşturulan C++ üstbilgisi, vec<T> kullanımı biraz kolaylık sağlar std::vector ve çıplak T arasında çeviri yapılacak işlevler kullanabilirsiniz. Parametre olarak vec<T> kullanılırsa (iki prototip oluşturulur) ve bunu kabul etmek için bunun için hem HIDL struct'ı hem de std::vector<T> türünü iletin parametresinden sonra bir değer girin.

dizi

Hidl'deki sabit diziler, hidl_array sınıfıyla temsil edilir. libhidlbase içinde. hidl_array<T, S1, S2, …, SN>, N boyutlu sabit boyutlu bir diziyi temsil eder T[S1][S2]…[SN].

dize

hidl_string sınıfı (libhidlbase öğesinin parçası) olabilir HIDL arayüzleri üzerinden dizeleri aktarmak için kullanılır ve /system/libhidl/base/include/hidl/HidlSupport.h. İlk depolama konumu, karakter arabelleğinin işaretçisidir.

hidl_string, ile hangi hedef için dönüşüm gerçekleştireceğini bilir std::string and char* (C stili dize) operator=, örtülü yayınlar ve .c_str() işlevi. HIDL dizesi yapılarında uygun kopya oluşturucu ve atama bulunur operatörlerini şu şekilde kullanabilirsiniz:

  • HIDL dizesini bir std::string veya C dizesinden yükleyin.
  • Bir HIDL dizesinden yeni bir std::string oluşturun.

Buna ek olarak, HIDL dizeleri dönüşüm oluşturucuları olduğundan C dizeleri (char *) ve C++ dizeleri (std::string) şurada kullanılabilir: HIDL dizesi alan yöntemler.

struct

HIDL'deki struct yalnızca sabit boyutlu veri türleri içerebilir ve hiçbir veri türünü içeremez işlevlerine dahildir. HIDL yapı tanımları doğrudan standart düzenle eşlenir struct C++'ta, struct sağlar. struct, aşağıdakiler dahil HIDL türlerini içerebilir: handle, string ve vec<T> arabellekleri bulmanızı sağlar.

herkese açık kullanıcı adı

UYARI: Her tür adres (fiziksel adres dahil) cihaz adresleri) hiçbir zaman yerel bir herkese açık kullanıcı adının parçası olmamalıdır. Geçiyorum bilgiler tehlikelidir ve saldırılara açık hale getirir. İşlemler arasında iletilen tüm değerler, sisteme bakmak için kullanılmadan önce doğrulanmalıdır. bir işlem sırasında ayrılan bellek miktarının arttığı anlamına gelir. Aksi takdirde, hatalı herkese açık kullanıcı adları sorun olabilir.

handle türü, hidl_handle ile temsil edilir yapısı, bir öğe üzerine işaretçiyi çevreleyen basit bir sarmalayıcıdır. const native_handle_t nesne (bu özellik Android'de şu kadar için kullanılıyordu: uzun süre korunuyor).

typedef struct native_handle
{
    int version;        /* sizeof(native_handle_t) */
    int numFds;         /* number of file descriptors at &data[0] */
    int numInts;        /* number of ints at &data[numFds] */
    int data[0];        /* numFds + numInts ints */
} native_handle_t;

Varsayılan olarak hidl_handle sahipliği almaz bir native_handle_t işaretidir. Yalnızca güvenli bir şekilde kullanılabilecek şekilde bir native_handle_t işaretçisini 32 ve 64 bit işlemler için kullanılabilir.

hidl_handle öğesinin kapalı dosyasına sahip olduğu senaryolar tanımlayıcılar şunları içerir:

  • shouldOwn parametresinin şu şekilde ayarlandığı setTo(native_handle_t* handle, bool shouldOwn) yöntemine yapılan bir çağrıyı takip etme true
  • hidl_handle nesnesi, kopya oluşturma ile oluşturulduğunda başka bir hidl_handle nesneden
  • hidl_handle nesnesi başka bir nesneden kopyaya atandığında hidl_handle nesne

hidl_handle, hem örtülü hem de açık dönüşümler sağlar ile native_handle_t* nesne arasında. Temel kullanım amacı HIDL'deki handle türü, dosya tanımlayıcılarını HIDL üzerinden iletmek için kullanılır kullanır. Dolayısıyla, tek bir dosya tanımlayıcısı bir int içermeyen ve tek bir native_handle_t fd. İstemci ve sunucu farklı bir süreçte yaşıyorsa RPC uygulama tarafından otomatik olarak dosya açıklayıcısı ile ilgilenmesi her iki işlem de aynı dosya üzerinde çalışabilir.

Bir dosya tanımlayıcısının hidl_handle içinde bir bu süreçte geçerli olduğundan, bu süreç alma işlevine (işlev döndüğünde kapanır). Bir süreç dosya tanımlayıcısına kalıcı erişimi korumayı sürdürmek için dup() veya hidl_handle nesnesinin tamamını kopyalayın.

bellek

HIDL memory türü hidl_memory sınıfıyla eşleşir libhidlbase, eşlenmemiş paylaşılan belleği temsil eder. Bu HIDL'de belleği paylaşmak için işlemler arasında iletilmesi gereken nesne. Alıcı: paylaşılan anıyı kullan:

  1. IAllocator (şu anda yalnızca örnek) "aşmem" kullanılabilir) ve paylaşılan belleği ayırmak için kullanın.
  2. IAllocator::allocate(), hidl_memory değeri döndürüyor HIDL RPC'sinden geçirilebilecek ve libhidlmemory işlevinin mapMemory işlevi.
  3. mapMemory, bir Hafızaya erişmek için kullanılabilecek sp<IMemory> nesne. (IMemory ve IAllocator şurada tanımlanmıştır: android.hidl.memory@1.0.)

Bellek tahsis etmek için bir IAllocator örneği kullanılabilir:

#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
using ::android::hidl::allocator::V1_0::IAllocator;
using ::android::hidl::memory::V1_0::IMemory;
using ::android::hardware::hidl_memory;
....
  sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
  ashmemAllocator->allocate(2048, [&](bool success, const hidl_memory& mem) {
        if (!success) { /* error */ }
        // now you can use the hidl_memory object 'mem' or pass it around
  }));

Hafızada yapılacak gerçek değişiklikler bir IMemory üzerinden yapılmalıdır. nesne ("mem") oluşturan tarafta veya bunu HIDL RPC üzerinden alır.

// Same includes as above

sp<IMemory> memory = mapMemory(mem);
void* data = memory->getPointer();
memory->update();
// update memory however you wish after calling update and before calling commit
data[0] = 42;
memory->commit();
// …
memory->update(); // the same memory can be updated multiple times
// …
memory->commit();

arayüz

Arayüzler nesne olarak iletilebilir. Arayüz kelimesi kullanılabilir android.hidl.base@1.0::IBase türü için söz dizimsel şeker olarak; Ayrıca, mevcut arayüz ve içe aktarılan arayüzler tanımlanmıştır. seçilebilir.

Arayüzleri barındıran değişkenler güçlü işaretçiler olmalıdır: sp<IName> Arayüz parametrelerini alan HIDL işlevleri ham işaretçileri güçlü işaretçilere dönüştürerek sezgisel olmayan davranışa neden olur (işaretçi beklenmedik bir şekilde silinebilir). Sorun yaşamamak için HIDL'yi her zaman saklayın sp<> olarak arayüz oluşturur.