внешний C и метод struct - PullRequest
6 голосов
/ 04 августа 2011

Учитывая следующий код C ++,

#ifdef __cplusplus
extern "C" {
#endif
        struct foo {
                void getNum() { 
                }
        };
#ifdef __cplusplus
}
#endif

int main (int argc, char * const argv[]) {
        return 0 ;
}

Можно ли позвонить getNum() из C?

Ответы [ 4 ]

7 голосов
/ 04 августа 2011

extern "C" не влияет на функцию-член: getNum() имеет связь с языком C ++.

Стандарт языка C ++ (C ++ 03 §7.5 / 4):

Связывание языка AC игнорируется для имен членов класса и типа функции-члена функций-членов класса.

Итак, нет, вы не можете вызвать эту функцию напрямую из программы на C (хотякак уже говорили другие, вы не можете скомпилировать этот код как C, так как C не имеет функций-членов).Разумеется, возможно, что некоторые реализации могут позволять вам вызывать эту функцию из программы на Си через какой-то специфический для реализации метод.

7 голосов
/ 04 августа 2011

Нет, поскольку getNum является функцией-членом, которой C не имеет.

Возможное решение этой проблемы - написать функцию C ++, которая возвращает экземпляр foo в виде foo* (где foo изменяется на пустую структуру) в C (я предполагаю, что это двоичный код, скомпилированный как C ++, на который ссылается C), затем в C ++ есть свободная функция с именем foo_getNum или чем-то еще, которая принимает foo* (определение которого модифицировано для версии C, чтобы быть пустой), которая вызывает getNum для нее. Хотя, очевидно, это не будет безопасно для типов (но взятие foo*, даже если foo пусто, будет лучше, чем void* - спасибо Дэвиду).

3 голосов
/ 04 августа 2011

Вы не можете вызывать эту функцию-член из C переносимым способом.Вам нужно раскрыть свой интерфейс C ++, сгладив его.

1 голос
/ 04 августа 2011

Код, который вы дали, не будет компилироваться в режиме C, так как компилятор C не поддерживает функции в структуре.Тем не менее, вы можете создать функцию в C ++, которая может вызывать это и связывать ее с C связью.Создайте 2 файла main.c и abc.cpp

Код для main.c

extern "C" void getNumCaller();
int main ()
{
    getNumCaller();
    return 0;
}

Код для abc.cpp

#include <iostream>

struct foo {
        void getNum() {
            std::cout << "calling getNum" << std::endl;
        }
};

extern "C" void getNumCaller()
{
    struct foo abc;
    abc.getNum();
}

Скомпилируйте код:

g++ -o abc abc.cpp main.c

и вы получите вывод:

calling getNum
...