Pembungkus idiomatis dari C ++ tipe templat API dalam C

9

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 keydan valueparameter. 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 signeddan unsignedversi jenis C, aku baik-baik dengan membatasi API untuk mendukung hanya int, double, float, char *untuk keydan 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, containsdengan semua kemungkinan kombinasi keydan valuejenis 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 keydan value, pemain seperti (void *) (intptr_t) intValakan 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.

Maks
sumber
Banyak upvotes, belum ada pendapat. Saya kumpulkan itu masalah umum bagaimana membungkus metode diketik template dalam C?
Maks.
Saya tidak yakin itu biasa. Saya terbalik karena saya menemukan masalah yang menarik.
MetaFight
Terkait, meskipun tidak terlalu membantu di sini: stackoverflow.com/questions/1588788/…
Martin Ba

Jawaban:

1

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:

struct Binary {
   byte *data;
   size_t length;
   int32_t dataType;
};
Binary *hazelcast_map_put(const Binary *key, const Binary *value);

Utilitas serialisasi:

int hazelcast_binary_to_int(const Binary *data);

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.

ihsan demir
sumber
Saya pikir ini adalah cara untuk menangani kasus saya. Untuk orang-orang yang keluar dari loop, saya juga mengajukan pertanyaan yang sama dalam PR ke klien hazelcast C ++ github.com/hazelcast/hazelcast-cpp-client/pull/127 dan ihsan, pengelola klien C ++ itu, sangat baik untuk menanggapi pertanyaan saya di SO, juga.
Maks