В первом варианте ( С++ ) у вас monitorlist* dd
во втором ( С ) struct monitorlist* dd;
Думаю в этом проблема.
И ещё я сомневаюсь что в вашей библиотеке ddccontrol monitorlist
определён как класс но думаю что его надо инициализировать через оператор new()
раз вы создали указатель monitorlist* dd;
Ну правильно получаете на сколько мне помнится все описания структур и классов в C++ должны быть в *.h файлах (объявления) а вот непосредственно реализация в *.cpp а у вас похоже винегрет :-) вот компоновщик и возмущается...
Дело в том что он по "хедерам вычисляет кому, сколько и где отвести памяти".
Если мне память не изменяет уж простите за тавтологию.
В хейдере описаны эти функции и структуры. #include <ddccontrol/ddcci.h>
Реализованы они в библиотеке libddccontrol.so | libddccontrol.a. (apt install libddccontrol-dev)
Как правильно воспользоваться этой библиотекой в моей программе?
Если ваша программа написана на С++ но должна вызывать С функции то обычно пишут wrapper библиотеки так проще хоть и появляются накладные расходы.
Создайте класс типа "ddccontrol" в конструкторе сделайте struct monitorlist* dd; dd = ddcci_probe();
возможно какие то поля структуры имеет смысл скопировать в переменные класса
в деструкторе ddcci_free_list(dd);
ну а в других методах-класса можно оставшиеся функции вызывать тут всё зависит от вашей фантазии и необходимости...
Создал хедер struct MonitorList{ public: MonitorList(); private: struct monitorlist* pListMonitor; };
и cpp #include "monitorlist.h" MonitorList::MonitorList(){ pListMonitor = ddcci_probe(); }
и main.cpp #include "monitorlist.h" int main(int argc, char *argv[]) { MonitorList list; return 0; }
Но снова ругается на
testLibs/monitorlist.cpp:3: undefined reference to `ddcci_probe()'
return 0;
При сборке поймал ошибку /usr/include/ddccontrol/monitor_db.h:26: ошибка: libxml/xmlstring.h: No such file or directory
что то на ночь глядя ничего умного в голову не пришло хотя похоже проблема тривиальна
если сталкивались то как решили ?
Посмотрел в отладке ddcci_probe() всегда возвращает 0x0 то есть структура не инициализирована и адрес не определён компилятор С это проглатывает поскольку за распределением памяти инициализацией переменных и прочее везде следит программист у С++ более жёсткие ограничения. Я бы посоветовал выкачать все исходники библиотеки не только хедеры и посмотреть реализацию и иерархию вызовов функций. Скорее всего до вызова ddcci_probe() надо сделать кучу подготовительных действий. Возможно в сорцах будет пример использования данной библиотеки.
Если прогу запустить с под root =) Она вернет список мониторов которыми можно управлять. Вот мой вывод. file: dev:/dev/i2c-4 (Unknown monitor (VSC3A2C))
Если я правильно понимаю процесс компиляции.. То компилятор С++ прекрасно смог создать объектные файлы. А проблемы появляются на следующем шаге. Линковщик не может найти функцию ddcci_probe() ls *.o main.o monitorlist.o
nm -D /usr/lib/x86_64-linux-gnu/libddccontrol.so.0 | grep ddcci_probe 0000000000004680 T ddcci_probe 00000000000044e0 T ddcci_probe_device
g++ -o MyProgram main.o monitorlist.o -lddccontrol monitorlist.o: In function `MonitorList::MonitorList()': monitorlist.cpp:4: undefined reference to `ddcci_probe()' collect2: error: ld returned 1 exit status
Ну если исходить из вашей логики то тогда правильней sudo g++ -o MyProgram main.o monitorlist.o -lddccontrol
у компоновщика должен быть полный доступ к файлам (не совсем догоняю зачем...)
но видимо так надо.
Я вспомнил у C++ есть особенность работы с внешними функциями pListMonitor = ddcci_probe();
надо перенести в обьявления класса (файл monitorlist.h) #ifndef MONITORLIST_H #define MONITORLIST_H extern "C" { #include <ddccontrol/ddcci.h> } class MonitorList { public:
В первом варианте ( С++ ) у вас
во втором ( С )
Думаю в этом проблема.
И ещё я сомневаюсь что в вашей библиотеке ddccontrol
monitorlist
определён как класс но думаю что его надо инициализировать через оператор
new()
раз вы создали указатель
monitorlist* dd;
Ну правильно получаете на сколько мне помнится все описания структур и классов в C++ должны быть в *.h файлах (объявления) а вот непосредственно реализация в *.cpp а у вас похоже винегрет :-) вот компоновщик и возмущается...
Дело в том что он по "хедерам вычисляет кому, сколько и где отвести памяти".
Если мне память не изменяет уж простите за тавтологию.
В хейдере описаны эти функции и структуры. #include <ddccontrol/ddcci.h>
Реализованы они в библиотеке libddccontrol.so | libddccontrol.a. (apt install libddccontrol-dev)
Как правильно воспользоваться этой библиотекой в моей программе?
Если ваша программа написана на С++ но должна вызывать С функции то обычно пишут wrapper библиотеки так проще хоть и появляются накладные расходы.
Создайте класс типа "ddccontrol" в конструкторе сделайте
struct monitorlist* dd;
dd = ddcci_probe();
возможно какие то поля структуры имеет смысл скопировать в переменные класса
в деструкторе
ddcci_free_list(dd);
ну а в других методах-класса можно оставшиеся функции вызывать тут всё зависит от вашей фантазии и необходимости...
Создал хедер
struct MonitorList{
public:
MonitorList();
private:
struct monitorlist* pListMonitor;
};
и cpp
#include "monitorlist.h"
MonitorList::MonitorList(){
pListMonitor = ddcci_probe();
}
и main.cpp
#include "monitorlist.h"
int main(int argc, char *argv[])
{
MonitorList list;
return 0;
}
Но снова ругается на
testLibs/monitorlist.cpp:3: undefined reference to `ddcci_probe()'
Решил потестировать ваш C код
struct monitorlist* dd;
dd = ddcci_probe();
while(dd != NULL){
printf("file: %s (%s)\n", dd->filename, dd->name);
dd = dd->next;
}
ddcci_free_list(dd);
return 0;
При сборке поймал ошибку
что то на ночь глядя ничего умного в голову не пришло хотя похоже проблема тривиальна
если сталкивались то как решили ?
Я установил библиотеку apt install libxml2-dev
И добавил в pro файл
INCLUDEPATH += /usr/include/libxml2
Тьфу ты забыл я про INCLUDEPATH спасибо.
Посмотрел в отладке
ddcci_probe()
всегда возвращает 0x0 то есть структура не инициализирована и адрес не определён компилятор С это проглатывает поскольку за распределением памяти инициализацией переменных и прочее везде следит программист у С++ более жёсткие ограничения. Я бы посоветовал выкачать все исходники библиотеки не только хедеры и посмотреть реализацию и иерархию вызовов функций. Скорее всего до вызова ddcci_probe() надо сделать кучу подготовительных действий. Возможно в сорцах будет пример использования данной библиотеки.Если прогу запустить с под root =) Она вернет список мониторов которыми можно управлять. Вот мой вывод.
file: dev:/dev/i2c-4 (Unknown monitor (VSC3A2C))
Если я правильно понимаю процесс компиляции.. То компилятор С++ прекрасно смог создать объектные файлы. А проблемы появляются на следующем шаге. Линковщик не может найти функцию ddcci_probe()
ls *.o
main.o monitorlist.o
nm -D /usr/lib/x86_64-linux-gnu/libddccontrol.so.0 | grep ddcci_probe
0000000000004680 T ddcci_probe
00000000000044e0 T ddcci_probe_device
g++ -o MyProgram main.o monitorlist.o -lddccontrol
monitorlist.o: In function `MonitorList::MonitorList()':
monitorlist.cpp:4: undefined reference to `ddcci_probe()'
collect2: error: ld returned 1 exit status
Ну если исходить из вашей логики то тогда правильней
sudo g++ -o MyProgram main.o monitorlist.o -lddccontrol
у компоновщика должен быть полный доступ к файлам (не совсем догоняю зачем...)
но видимо так надо.
Я вспомнил у C++ есть особенность работы с внешними функциями
pListMonitor = ddcci_probe();
надо перенести в обьявления класса (файл monitorlist.h)
#ifndef MONITORLIST_H
#define MONITORLIST_H
extern "C"
{
#include <ddccontrol/ddcci.h>
}
class MonitorList
{
public:
struct monitorlist* pListMonitor;
MonitorList(){
pListMonitor = ddcci_probe();}
};
#endif // MONITORLIST_H
файл (main.cpp)
#include "monitorlist.h"
int main(int argc, char *argv[])
{
MonitorList List();
return 0;
}
файл реализации (monitorlist.cpp)
у меня пустой.
Всё прекрасно компилируется.
Огромное спасибо =)
Отправить комментарий