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 etmetrue
hidl_handle
nesnesi, kopya oluşturma ile oluşturulduğunda başka birhidl_handle
nesnedenhidl_handle
nesnesi başka bir nesneden kopyaya atandığındahidl_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:
IAllocator
(şu anda yalnızca örnek) "aşmem" kullanılabilir) ve paylaşılan belleği ayırmak için kullanın.IAllocator::allocate()
,hidl_memory
değeri döndürüyor HIDL RPC'sinden geçirilebilecek velibhidlmemory
işlevininmapMemory
işlevi.mapMemory
, bir Hafızaya erişmek için kullanılabileceksp<IMemory>
nesne. (IMemory
veIAllocator
ş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.