C语言中C ++模板类型API的惯用包装


9

我正在包装一个C ++ API,该API提供对C函数中的数据存储(Hazelcast)的访问,以便也可以从仅C代码中访问数据存储。

用于Map数据结构的Hazelcast C ++ API如下所示:

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

它使用key和和的模板类型value。由于C中没有可用的模板,因此我考虑为该getMap<T, U>方法的每种特殊化创建包装函数。也就是说,对于每种C类型。虽然我知道有signedunsignedC型的版本,我很好限制API仅支持intdoublefloatchar *keyvalue

所以我写了一个小脚本,可以自动生成所有组合。导出的函数如下所示:

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

...

生成功能getsetcontains与所有可能的组合keyvalue种类增加了代码的数量相当多,虽然我觉得生成的代码是一个好主意,它具有创造某种代码生成的基础设施增加了额外的复杂性。

我可以想象的另一个想法是C中的一个泛型函数,如下所示:

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和and 的类型value一样(void *) (intptr_t) intVal,在调用者那边需要强制转换,这同样也不是很容易阅读和维护。

  • 还有我不认识的第三种选择吗?
  • C开发人员将首选哪个版本?

尽管头文件会变得非常庞大,但我主要倾向于自动生成所有类型组合并为每个类型创建一个函数。


许多投票,还没有意见。我知道如何在C中包装模板类型的方法是一个常见的问题?
Max

我不确定这很普遍。我投票赞成,因为我发现这个问题很有趣。
MetaFight

相关,虽然方便这里并不是真的那么:stackoverflow.com/questions/1588788/...
马丁巴

Answers:


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#serializationhttps://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 ++客户端的维护者ihsan的表现很好在这里也回答我的问题。
Max
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.