Ідіоматичне обгортання API шаблону типу C ++ у C


9

Я працюю над упаковкою API C ++, який забезпечує доступ до сховища даних (Hazelcast) у функціях C, так що до сховища даних також можна отримати доступ з коду, що містить лише C.

API Hazelcast C ++ для структури даних Map виглядає приблизно так:

auto map = hazelcastClient->client->getMap<int, string>(mapName);
map.put(key, value);

Він використовує типи шаблонів для keyта valueпараметрів. Оскільки в C немає шаблонів, я думав про створення функції обгортки для кожної спеціалізації getMap<T, U>методу. Тобто для кожного типу С. Хоча я знаю , що є signedі unsignedваріанти типів C, я штраф з обмеженням API для підтримки тільки int, double, float, char *для keyі value.

Тому я написав невеликий сценарій, який автоматично генерує всі комбінації. Експортовані функції виглядають приблизно так:

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
);

...

Створення функції для get, set, containsз усіма можливими комбінаціями keyі valueтипами збільшує кількість коди досить багато, і , хоча я думаю , що генерування коди є хорошою ідеєю, це докладає додаткову складність, маючи для створення якого - то код , що генерує інфраструктури.

Ще одна ідея, яку я можу собі уявити, - це одна загальна функція в С, як це:

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
);

Які можна використовувати так:

Hazelcast_Map_put(client, mapName, "key", API_TYPE_STR, "val", API_TYPE_STR, &err);

Це полегшує для абонента, оскільки він перекладає тягар отримання правильної спеціалізації на мій код, але він втрачає безпеку типу і вимагає кастингу. Крім того, для передачі в int, як void *зараз є тип, keyа також valueпотрібен акторський (void *) (intptr_t) intValсклад на стороні абонентів, що знову не дуже приємно читати та підтримувати.

  • Чи є якийсь третій варіант, який я не можу розпізнати?
  • Якій версії віддадуть перевагу розробники C?

Я здебільшого схильний до автоматичного генерування всіх комбінацій типів та створення функції для кожного, хоча, мабуть, файл заголовка стане досить величезним.


Багато відгуків, думки поки немає. Я знаю, це поширена проблема, як обернути шаблонні методи, введені в C?
Макс

Я не впевнений, що це звичайне явище. Я підтримав рішення, оскільки вважаю проблему цікавою.
MetaFight

Пов’язане, хоча й не дуже корисне тут: stackoverflow.com/questions/1588788/…
Martin Ba

Відповіді:


1

Створення для всіх можливостей не виглядало для мене дуже вдалим рішенням. Ключем і значеннями можуть бути і об'єкти. Отже, можливості нескінченні :(

Ви ознайомилися з класом IMapImpl? Цей клас використовує не типи, а двійкові дані (які надаються після серіалізації). Отже, іншим рішенням буде написання API, що імітує цей інтерфейс +, надаючи утиліту серіалізації, яка перетворює будь-який тип у бінарний, який потрібен цьому інтерфейсу.

Напр

API:

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

Утиліта серіалізації:

int hazelcast_binary_to_int(const Binary *data);

Можливо, вам потрібно буде написати ці допоміжні функції для типів об'єктів, які ви хочете підтримати. Це може бути життєздатний інтерфейс. Є такі речі, які слід враховувати, наприклад, управління пам'яттю.

Серіалізація - складний предмет, але ви, безумовно, можете почати спочатку з підтримки первісних типів. Див. Http://docs.hazelcast.org/docs/3.6/manual/html-single/index.html#serialization та https://github.com/hazelcast/hazelcast/blob/master/hazelcast/src/main/java /com/hazelcast/internal/serialization/impl/ConstantSerializers.java для деталей серіалізації.


Я думаю, що це шлях до моєї справи. Для людей, які вийшли з циклу, я також задав те саме питання в PR-програмі клієнтові hazelcast C ++ github.com/hazelcast/hazelcast-cpp-client/pull/127, а їхній власник клієнта C ++ був їх таким приємним, як щоб відповісти на моє запитання тут і на ТАК.
Макс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.