การห่อตามปกติของ C ++ เทมเพลตประเภท API ใน C


9

ฉันกำลังทำงานกับการห่อ C ++ API ซึ่งให้การเข้าถึงแหล่งข้อมูล (Hazelcast) ในฟังก์ชัน C เพื่อให้ที่เก็บข้อมูลสามารถเข้าถึงได้จากรหัส C เท่านั้น

Hazelcast C ++ API สำหรับโครงสร้างข้อมูลแผนที่มีลักษณะดังนี้:

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

มันใช้ประโยชน์จากประเภทแม่แบบkeyและvalueพารามิเตอร์ เนื่องจากไม่มีเทมเพลตใน C ฉันจึงคิดเกี่ยวกับการสร้างฟังก์ชั่น wrapper สำหรับแต่ละความเชี่ยวชาญของgetMap<T, U>วิธี นั่นคือสำหรับแต่ละประเภท C แม้ว่าฉันรู้ว่ามีsignedและunsignedรุ่นของประเภท C, ฉันดีกับการ จำกัด 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กับชุดที่เป็นไปได้ทั้งหมดkeyและvalueประเภทเพิ่มปริมาณของรหัสที่ค่อนข้างมากและแม้ว่าผมคิดว่าการสร้างรหัสเป็นความคิดที่ดีที่จะเพิ่มความซับซ้อนเพิ่มเติมโดยมีการสร้างโครงสร้างพื้นฐานชนิดของรหัสที่ก่อให้บาง

ความคิดอื่นที่ฉันสามารถจินตนาการได้คือฟังก์ชันทั่วไปหนึ่งตัวใน 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และvalueนักแสดงที่ต้องการ(void *) (intptr_t) intValจะต้องอยู่ด้านการโทรซึ่งอีกครั้งไม่ดีมากที่จะอ่านและบำรุงรักษา

  • มีตัวเลือกที่สามซึ่งฉันจำไม่ได้หรือไม่
  • นักพัฒนา C รุ่นใดที่เป็นที่ต้องการ

ฉันมักจะสร้างชุดค่าผสมทุกประเภทโดยอัตโนมัติและสร้างฟังก์ชั่นสำหรับแต่ละชุดแม้ว่าไฟล์ส่วนหัวจะค่อนข้างใหญ่


upvotes หลายคนยังไม่มีความคิดเห็น ฉันรวบรวมเป็นปัญหาทั่วไปวิธีห่อวิธีพิมพ์แม่แบบใน 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#serializationและhttps://github.com/hazelcast/hazelcast/blob/master/hazelcast/src/main/java /com/hazelcast/internal/serialization/impl/ConstantSerializers.javaสำหรับรายละเอียดการทำให้เป็นอนุกรม


ฉันคิดว่านี่เป็นวิธีที่จะไปสำหรับกรณีของฉัน สำหรับคนที่ไม่อยู่ในลูปฉันก็ถามคำถามเดียวกันใน PR ไปยังไคลเอนต์เฮเซลคาสท์ C ++ github.com/hazelcast/hazelcast-cpp-client/pull/127และ ihsan ผู้ดูแลลูกค้า C ++ นั้นดีมากเช่นกัน เพื่อตอบคำถามของฉันที่นี่ใน SO ด้วย
สูงสุด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.