Как связать C ++ для использования переменной, определенной в статической библиотеке C (символ не найден, ошибка)

0

У меня есть статическая библиотека C, в которой определена глобальная переменная структуры. Я хочу получить доступ к этой переменной в коде C++, который будет ссылаться на эту библиотеку C. На данный момент я получаю "ld: символы (символы), которые не найдены для архитектуры x86_64".

Я пытаюсь сделать следующее (упрощенная структура для вопроса):

// library.h
#ifdef __cplusplus
  extern "C" {
#endif

typedef struct {
  int simpleVariableA;
  int simpleVariableB;
} GlobalStruct;

extern GlobalStruct gs;
#ifdef __cplusplus
  }
#endif

// library.c
#include "library.h"
GlobalStruct gs;

Library.c и library.h скомпилированы в library.a, статически связанную библиотеку. Затем я хочу связать файл C++ с библиотекой, но получить ошибки.

// main.cpp
#include "library.h"

int main(int argc, char** argv) {
  gs.simpleVariableA = 1;
  gs.simpleVariableB = 1;
}

Что я делаю не так? Я запустил "nm -g library.a" и получил "0000000000000008 C _gs", поэтому я думаю, что это означает, что символ экспортируется, нет? Это проблема с C++, не находя C-код?

Я компилирую файлы следующим образом:

gcc -c library.c -o library.o
ar rcs liblibrary.a library.o
g++ main.cpp -L. -llibrary

BTW, я получаю сообщение об ошибке с командой ar:

warning: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: warning for library: liblibrary.a the table of contents is empty (no object file members in the library define global symbols)

Однако эта ошибка исчезает, если я определяю функцию f() в библиотеке.h и library.c и компилирую ее в библиотеку.

  • 0
    Хм хотя бы это предупреждение: / ...
Теги:
static-libraries

1 ответ

3
Лучший ответ

Каждое из ваших упоминаний о gs - это просто объявление (то есть оно указывает на то, что есть что-то под этим именем где-то), но ни одно из них не является определением (которое является чем-то, что дополнительно выделяет пространство для названной вещи).

Если вы инициализируете gs в library.c, ваша проблема исчезнет:

GlobalStruct gs = { 0, 0 };

Функция ключевого слова extern в вашей library.h заключается в том, чтобы остановить это определение (предварительное). В этом случае он может быть избыточным, но, вероятно, лучше всего включить его, поэтому убедитесь, что в library.c есть только одно определение gs.

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

  • 0
    Отлично, большое спасибо. Я не осознавал, что отсутствие установки переменной в качестве начального значения означает, что она на самом деле не определена должным образом, я думал, что упоминание ее в файле .c означает, что она полностью определена.
  • 0
    Такова Радость С! Рад помочь....
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню