Saya sedang mengerjakan pembungkus C ++ API yang menyediakan akses ke penyimpanan data (Hazelcast) dalam fungsi C, sehingga penyimpanan data juga dapat diakses dari kode C-only.
API Hazelcast C ++ untuk datastructure Map terlihat seperti ini:
auto map = hazelcastClient->client->getMap<int, string>(mapName);
map.put(key, value);
Itu menggunakan jenis template untuk key
dan value
parameter. Karena tidak ada template yang tersedia di C, saya berpikir untuk membuat fungsi wrapper untuk setiap spesialisasi getMap<T, U>
metode. Yaitu, untuk setiap tipe C. Walaupun saya menyadari bahwa ada signed
dan unsigned
versi jenis C, aku baik-baik dengan membatasi API untuk mendukung hanya int
, double
, float
, char *
untuk key
dan value
.
Jadi saya menulis skrip kecil, yang secara otomatis menghasilkan semua kombinasi. Fungsi yang diekspor terlihat seperti ini:
int Hazelcast_Map_put_int_string(
Hazelcast_Client_t *hazelcastClient,
const char *mapName,
int key,
char *value,
char** errptr
);
int Hazelcast_Map_put_int_int(
Hazelcast_Client_t *hazelcastClient,
const char *mapName,
int key,
int value,
char** errptr
);
...
Fungsi pembangkit untuk get
, set
, contains
dengan semua kemungkinan kombinasi key
dan value
jenis meningkatkan jumlah kode cukup banyak, dan meskipun saya pikir menghasilkan kode adalah ide yang baik, itu menambah kompleksitas tambahan dengan memiliki untuk membuat semacam infrastruktur kode-pembangkit.
Gagasan lain yang bisa saya bayangkan adalah satu fungsi generik dalam C, seperti ini:
int Hazelcast_Map_put(
Hazelcast_Client_t *hazelcastClient,
const char *mapName,
const void *key,
API_TYPE key_type,
const void *value,
API_TYPE value_type,
char** errptr
);
Yang bisa digunakan seperti ini:
Hazelcast_Map_put(client, mapName, "key", API_TYPE_STR, "val", API_TYPE_STR, &err);
Ini membuatnya sedikit lebih mudah bagi penelepon, karena itu menggeser beban untuk mendapatkan spesialisasi yang benar pada kode saya, tetapi kehilangan jenis keamanan dan membutuhkan gips. Juga, untuk melewati int, seperti void *
sekarang jenis key
dan value
, pemain seperti (void *) (intptr_t) intVal
akan diperlukan di sisi penelepon, yang lagi-lagi tidak super bagus untuk dibaca dan dipelihara.
- Apakah ada opsi ketiga, yang tidak bisa saya kenali?
- Versi mana yang lebih disukai oleh pengembang C?
Saya sebagian besar cenderung untuk secara otomatis menghasilkan semua kombinasi jenis dan membuat fungsi untuk masing-masing, meskipun saya kira file header akan menjadi sangat besar.
sumber
Jawaban:
Menghasilkan untuk semua kemungkinan tidak terlihat menjadi solusi yang sangat baik bagi saya. Kunci dan nilai-nilai juga bisa berupa objek. Oleh karena itu, kemungkinannya tidak terbatas :(
Apakah Anda sudah melihat kelas IMapImpl? Kelas ini tidak menggunakan tipe tetapi data biner (yang disediakan setelah serialisasi). Oleh karena itu, solusi lain adalah menulis API yang meniru antarmuka ini + menyediakan utilitas Serialisasi yang mengubah jenis apa pun yang diberikan ke biner yang dibutuhkan antarmuka ini.
Misalnya
API:
Utilitas serialisasi:
Anda mungkin perlu menulis fungsi pembantu ini untuk jenis objek yang ingin Anda dukung. Ini mungkin antarmuka yang layak. Ada beberapa hal yang harus dipertimbangkan seperti manajemen memori.
Serialisasi adalah subjek yang kompleks, tetapi Anda pasti dapat memulai dengan mendukung tipe primitif terlebih dahulu. Lihat http://docs.hazelcast.org/docs/3.6/manual/html-single/index.html#serialisasi dan https://github.com/hazelcast/hazelcast/hazelcast/blob/master/hazelcast/src/main/java /com/hazelcast/internal/serialization/impl/ConstantSerializers.java untuk detail serialisasi.
sumber