Связывание другой библиотеки из C-библиотеки в gwan/libraries приводит к ошибке неопределенного символа

Я пытаюсь использовать стандартную библиотеку libuuid внутри моего файла C-библиотеки my_uuid.c:

гван/библиотеки/my_uuid.c:

#include <uuid/uuid.h>
#pragma link "uuid"
void my_uuid_generate(uuid_t uuid)
{
  uuid_generate(uuid);
}

Гван/init.c:

#include <uuid/uuid.h>
#pragma link "uuid"
#pragma link "libraries/my_uuid.c"
int main(int argc, char *argv[])
{
  uuid_t uuid;
  my_uuid_generate(uuid);
  return 0;
}

Однако G-Wan не запускается и выводит такое сообщение:

Связывание ./init.c: неопределенный символ: uuid_generate

Это не должно быть проблемой установки libuuid или нестандартного пути, потому что такой сервлет работает успешно:

#include <uuid/uuid.h>
#pragma link "uuid"
int main(int argc, char *argv[])
{
   uuid_t uuid;
   char str[256];

   uuid_generate(uuid);
   uuid_unparse(uuid, str);
   printf("%s\n", str);

   xbuf_cat(get_reply(argv), "Hello, World!");
   return 200;
}

Проблема может быть связана с тем, что G-Wan сначала загружает init.c, а затем my_uuid.c вместо libuuid, хотя у меня есть ссылка #pragma "uuid" в init.c.

Кто-нибудь знает, как решить проблему? Допустимо ли связывать другие библиотеки из библиотек C-файлов в gwan/libraries?


person soundwave    schedule 10.09.2016    source источник
comment
Библиотеки C-файлов, как вы их называете, не предназначались для использования G-WAN, поэтому мой ответ ниже. Кроме того, у динамического связывания есть накладные расходы (память, строки кэша, кэши ЦП), что означает, что вы должны использовать его только для больших библиотек, размер которых дисквалифицирует напрямую связанный объектный код, поскольку он может дублироваться, если используется несколькими сценариями G-WAN.   -  person Gil    schedule 18.09.2016


Ответы (3)


Я прочитал документацию GWAN. Если вы пишете свою собственную библиотеку, вы должны иметь возможность хорошо интегрироваться с ней (рассматривая ее как уже существующую библиотеку).

myuuid.h
myuuid.c

Затем создайте свою библиотеку, скомпилировав myuuid.c:

libmyuuid.a

Поместите библиотеку как gwan/libraries/libuuid.a и попробуйте, как показано ниже.

#include "myuuid.h"
#pragma link "./libraries/myuuid"

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

Вы можете следить за файлом gwan/logs/gwan.log, чтобы увидеть, работает ли ссылка. Вы также можете запустить сервер GWAN в терминале вручную, чтобы просмотреть ошибки.

person blackpen    schedule 11.09.2016
comment
Спасибо, но, к сожалению, это также работает, только если я поставлю ссылку #pragma uuid в конец файла init.c (как и в моем последнем ответе), в противном случае произойдет сбой с той же ошибкой. Связывание ./init.c: неопределенный символ: uuid_generate. - person soundwave; 11.09.2016

servlet работает, потому что вы напрямую связываете свой скрипт с существующей библиотекой (уже скомпилированный код).

Сценарий init.c не может связать, потому что библиотека "#pragma link "libraries/my_uuid.c", которая вызывает скомпилированную библиотеку, еще не существует (это все еще исходный код).

Вам лучше использовать #include "libraries/my_uuid.c" в init.c, чтобы такие конструкции работали.

person Gil    schedule 11.09.2016
comment
Если my_uuid.c еще не существует в виде двоичного файла, я ожидаю, что init.c завершится сбоем в my_uuid_generate(), но он не выполнится в uuid_generate() — что должно означать, что my_uuid.c был переведен в двоичную библиотеку. Я прав? Если я ошибаюсь, как компоновщик узнает о вызове uuid_generate() из еще не переведенного в двоичный файл my_uuid.c? - person soundwave; 11.09.2016

Интересно, что G-Wan успешно запустился, когда я переместил ссылку #pragma "uuid" ниже ссылки #pragma "libraries/my_uuid.c" в файле init.c:

#include <uuid/uuid.h>
#pragma link "libraries/my_uuid.c"
#pragma link "uuid"
int main(int argc, char *argv[])
{
  uuid_t uuid;
  my_uuid_generate(uuid);
  return 0;
}

Определенно изменился порядок, в котором G-Wan загружает libuuid и my_uuid.c. Теперь он сначала загружает libuuid (с символом uuid_generate()), а затем my_uuid.c (с символом my_uuid_generate(), который, в свою очередь, вызывает uuid_generate()).

Гил, правильно ли я понимаю, что в настоящее время G-Wan не предназначен для обеспечения контролируемого порядка загрузки библиотек? Может ли команда G-Wan рассмотреть возможность обновления сервера G-Wan для загрузки библиотек в контролируемом/предсказуемом порядке, хотя бы в некоторой степени? т.е. загружать зависимости перед пользователями зависимостей. Например, мы должны быть в состоянии написать такой код, как показано ниже, и сервер G-Wan должен загрузить сначала libuuid, затем my_uuid.c, затем init.c:

гван/библиотеки/my_uuid.c:

#pragma link "uuid"

Гван/init.c:

#pragma link "libraries/my_uuid.c"

(обратите внимание на отсутствие ссылки #pragma "uuid" в init.c)

person soundwave    schedule 11.09.2016
comment
Я не думаю, что GWAN имеет большой контроль над загрузкой библиотек (или их порядком). Он просто передает файлы .C компилятору/компоновщику (отдельно или вместе, в зависимости от ОС/среды и других факторов). Компилятор извлекает параметры прагмы/компоновщика и вставляет их в командную строку компоновщика. - person blackpen; 13.09.2016
comment
В приведенном на их сайте примере curl ничего не говорится о размещении кода начальной загрузки в файле init.c. - person blackpen; 13.09.2016