Referenz als Pointer bzw. umgekehrt bei Parameterübergabe



  • Hallo,

    ich wollte einmal erfragen, inwiefern ich in einer C++ Bibliothek mit Referenzen arbeiten kann und in einer C Bibliothek mit Zeigern, weil Referenzen teilweise bequemer sind und anzeigen, dass NULL nicht erwünscht ist.
    Also z.B. in einer Lib (z.B. dll) sei folgende Funktion implementiert:

    //  libintern.h
    extern "C" APIEXPORT foo(int& ri);
    

    Mit der Lib würde ich folgenden Header ausliefern:

    //  libpublic.h
    #ifdef __cplusplus
    extern "C" APIIMPORT foo(int& ri);
    #else
    //  note:  pi must not be NULL.
    APIIMPORT foo(int* pi);
    #endif
    

    Standardkonform? (wohl eher nicht, weil ABI)
    Möglich? (die lib hat in der Regel ein ähnliches ABI, wie der libclient)
    Alternativen?

    thx im vor*** 😮

    MfG
    DDR-RAM



  • Desweiteren würde mich interessieren, wie es sich mit ähnlichem verhält:

    //  libintern.h
    struct param {  int* x;  }
    extern "C" APIEXPORT bar(param a1);
    
    //  libpublic.h
    #ifdef __cplusplus
    struct param {  int* x;  }
    extern "C" APIIMPORT foo(param a1);
    #else
    //  note:  pi must not be NULL.
    APIIMPORT foo(int* a1);
    #endif
    

    Also, sagt der C-Standard irgendetwas dazu aus?

    MfG
    DDR-RAM



  • Zum ersten: Ich glaube nicht dass extern "C" und Referenzen sich vertragen, sagt doch ersteres aus, dass die Funktion C-Aufruf-(und Namens-)konventionen folgen soll, und C nunmal keine Referenzen kennt. Üblich wäre eher sowas, besonders wenn Du die Bibliothek in C und C++ nutzen wollen würdest:

    #ifdef __cplusplus
    extern "C" {
    #endif
    APIIMPORT foo(int* pi);
    #ifdef __cplusplus
    }
    #endif
    

    Was allerdings der Standard dazu sagt kann ich Dir nicht sagen, jedoch würde ich morgen (wenn nichts dazwischen kommt) wohl selbst da mal nachforschen, da es mich selbst interessieren würde 😉


  • Mod

    DDR-RAM schrieb:

    Hallo,

    ich wollte einmal erfragen, inwiefern ich in einer C++ Bibliothek mit Referenzen arbeiten kann und in einer C Bibliothek mit Zeigern, weil Referenzen teilweise bequemer sind und anzeigen, dass NULL nicht erwünscht ist.
    Also z.B. in einer Lib (z.B. dll) sei folgende Funktion implementiert:

    //  libintern.h
    extern "C" APIEXPORT foo(int& ri);
    

    Mit der Lib würde ich folgenden Header ausliefern:

    //  libpublic.h
    #ifdef __cplusplus
    extern "C" APIIMPORT foo(int& ri);
    #else
    //  note:  pi must not be NULL.
    APIIMPORT foo(int* pi);
    #endif
    

    Standardkonform? (wohl eher nicht, weil ABI)
    Möglich? (die lib hat in der Regel ein ähnliches ABI, wie der libclient)
    Alternativen?

    thx im vor*** 😮

    MfG
    DDR-RAM

    Das dürfte eine Grauzone sein - extern "C" dient dem Wortlaut des Standards zufolge dazu, Funktionen, die in C geschrieben sind, zu deklarieren. Ob das voraussetzt, dass diese Funktion in C tatsächlich so schreibbar ist, ist damit nicht unbedingt geklärt. Allerdings gibt es eine einfache Alternative:

    //  libintern.h
    namespace detail
    {
    extern "C" APIEXPORT foo(int* ri);
    }
    inline void foo(int& ri) { detail::foo( &ri ); }
    

    und

    //  libpublic.h
    #ifdef __cplusplus
    namespace detail
    {
    extern "C"
    #endif
    APIIMPORT foo(int* ri);
    #ifdef __cplusplus
    }
    inline void foo(int& ri) { detail::foo( &ri ); }
    #endif
    

    Der zweite Fall dürfte undefiniertes Verhalten haben (auch wenn es wohl regelmäßig funktionieren wird). Allerdings sollte er sich ganz analog behandeln lassen.


Anmelden zum Antworten