Преобразование пустой функции списка параметров из C в C ++ - PullRequest
0 голосов
/ 26 июня 2018

Я работаю над проектом, в котором я пытаюсь скомпилировать VXWorks END на C ++.Я не думаю, что смогу изменить работу в C ++, и я определенно не могу слишком сильно изменить VxWorks.

Все прошло нормально, за исключением одного вопроса.VxWorks требует, чтобы все драйверы регистрировали свои методы в структуре net_funcs, которая имеет следующие поля (среди прочих):

#ifdef __cplusplus
extern "C" {
#endif
...

typedef struct net_funcs
    {
    ...
    STATUS (*pollSend) (END_OBJ*, M_BLK_ID); /* Driver's polling send func. */
    STATUS (*pollRcv) (END_OBJ*, M_BLK_ID); /* Driver's polling recv func. */

    /*
     * The minimum required arguments for (*formAddress)() are:
     * (*formAddress)(M_BLK_ID, M_BLK_ID, M_BLK_ID, BOOL)
     */
    M_BLK_ID (*formAddress) ();           /* Driver's addr formation func. */

    /*
     * The minimum required arguments for (*packetDataGet)() are:
     * (*packetDataGet)(M_BLK_ID, LL_HDR_INFO *)
     */
    STATUS (*packetDataGet) ();           /* Driver's addr formation func. */
    ...
    } NET_FUNCS
...
#ifdef __cplusplus
}
#endif

Обратите внимание на пустой список параметров в стиле C.В Си это означает, что это поле может быть функтором, который принимает любой аргумент;однако при компиляции в C ++ он рассматривает эти аргументы как (void), а затем выдает ошибку, когда я пытаюсь создать экземпляр структуры.Если я пытаюсь изменить аргументы на (first arg, ...), то передача вызовов по умолчанию из lib-файла (endEtherAddressForm и endEtherPacketDataGet, которые оба вызываются из lib-файла в соответствии с рекомендациями руководства по программному обеспечению) вызывает ошибку, поскольку для этих функторов требуются четыре конкретныхаргументы и не принимают переменные числа аргументов.

Я мог бы просто жестко закодировать его в список аргументов функций по умолчанию и надеяться на лучшее, но прежде чем я это сделаю, есть ли способ сделатьэтот код работает с переменным списком аргументов в C и C ++?Или я должен что-то сделать, чтобы структура extern "C" работала с двумя файлами?

ОБНОВЛЕНИЕ:

При создании экземпляра структуры я использую следующий код:

LOCAL NET_FUNCS MBbufferNetFuncs =
    {
    ...
    MyCode::EndPollSend,
    MyCode::EndPollRcv,
    endEtherAddressForm, /* Library function from endLib.lib; declaration
        M_BLK_ID endEtherAddressForm(M_BLK_ID, M_BLK_ID, M_BLK_ID, BOOL)*/
    endEtherPacketDataGet /* Library function from endLib.lib; declaration
        STATUS endEtherAddressForm(M_BLK_ID, LL_HDR_INFO *)*/
    }

Ошибка гласит:

"A value of type "M_BLK_ID (*)(M_BLK_ID, M_BLK_ID, M_BLK_ID, BOOL)" cannot be used to initialize an entry of type "M_BLK_ID (*)()""

Обычно можно подумать, что объявление extern "C" в начале объявления net_func предотвратит проблемы с пустым списком параметров, но это недело.Я не знаю, нужно ли мне добавлять специальный код, когда я объявляю свою личную копию структуры, но она не работает.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Я немного устала от C и C ++, но если память служит ...

Синтаксис C для аргументов функции:

void foo1();              // Zero or more unspecified args
void foo2(int a, ...);    // One or more args
void foo3(void);          // No args

Синтаксис C ++:

void bar1(...);           // Zero or more unspecified args
void bar2(int a, ...);    // One or more args
void bar3();              // No args
0 голосов
/ 26 июня 2018

Я не могу проверить ваши настройки, но я обнаружил (clang -Wpedantic) доволен:

extern "C" int f(...);
int r(int c) {
    return f(c) * c;
}
int main(void) { 
    return r(2);
}

Это даже сработало, поэтому не должно быть неопределенного поведения ... :) Однако вынужно сделать что-то более уродливое, например:

ifdef __cplusplus
#define CLARGS ...
#else
#define CLARGS
#endif

, а затем сделать свои заявления:

M_BLK_ID (*formAddress) (CLARGS);

, чтобы предотвратить утечку C ++ в ваш код C.

...