C에서 C ++ 템플리트 유형 API의 관용적 랩핑


9

C 함수의 데이터 저장소 (Hazelcast)에 대한 액세스를 제공하는 C ++ API를 래핑하여 데이터 저장소를 C 전용 코드에서 액세스 할 수도 있습니다.

맵 데이터 구조를위한 Hazelcast C ++ API는 다음과 같습니다.

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

템플릿 유형 keyvalue매개 변수를 사용합니다. C에서 사용할 수있는 템플릿이 없으므로 각 getMap<T, U>메소드의 전문화를 위해 래퍼 함수를 ​​만드는 것에 대해 생각했습니다 . 즉, 각 C 유형마다. 나는이 있다는 것을 알고 있어요하지만 signedunsignedC 유형의 버전, 난 단지 지원하는 API 제한과 벌금을 해요 int, double, float, char *위해 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
);

...

하는 기능을 생성 get, set, contains모든 가능한 조합과 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);

이것은 코드에서 올바른 전문화를 얻는 부담을 옮기기 때문에 호출자에게 조금 더 쉬워 지지만 유형 안전을 잃고 캐스트가 필요합니다. 또한 in void *의 유형 을 전달하기 위해 이제와의 유형 keyvalue마찬가지로 (void *) (intptr_t) intVal호출자 측에 캐스트 가 필요하므로 다시 읽고 유지 관리하는 것이 좋지 않습니다.

  • 인식 할 수없는 세 번째 옵션이 있습니까?
  • C 개발자가 선호하는 버전은 무엇입니까?

헤더 파일이 상당히 커지더라도 모든 유형 조합을 자동 생성하고 각각에 대한 함수를 만드는 경향이 있습니다.


많은 의견, 아직 의견이 없습니다. 템플릿 유형의 메소드를 C로 래핑하는 방법이 일반적인 문제라고 생각합니까?
Max

나는 그것이 일반적인지 잘 모르겠습니다. 문제가 흥미로워 서 투표했습니다.
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#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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.