Re: Линковка сишной библиотеки в CPP
От: Cyberax Марс  
Дата: 26.04.10 14:35
Оценка: +1
Здравствуйте, cpp_beginner, Вы писали:

_>
_>// для создания указателя на сишную структуру
_>extern "C" struct xnee_data;
_>
Sapienti sat!
Линковка сишной библиотеки в CPP
От: cpp_beginner  
Дата: 26.04.10 08:52
Оценка:
Использую сишную библиотеку libxnee в проекте C++
Создаю класс обертки xnee_wrapper.
Подключаю хедеры в xnee_wrapper.h (перед всеми остальными хедерами)
extern "C"{
#include "libxnee/print.h"
#include "libxnee/xnee.h"
#include "libxnee/xnee_record.h"
#include "libxnee/xnee_grab.h"
#include "libxnee/xnee_alloc.h"
#include "libxnee/xnee_replay.h"
#include "libxnee/xnee_setget.h"
#include "libxnee/xnee_fake.h"
#include "libxnee/xnee_error.h"
#include "libxnee/xnee_session.h"
}

#include <map>
#include <string>

class xnee_wrapper{
...


Ругается на multiple definition

g++ -o xtrace main.o cmd_params.o xnee_wrapper.o -lxnee -lX11 -lXtst -ldl -lpthread -lboost_program_options
cmd_params.o: (.bss+0x0) : multiple definition of `xnee_data_types'
...


Стражи включения есть!

Переношу секцию extern "C" в xnee_wrapper.cpp — линкуется.
Но в этом случае не работает упреждающее определение типов.
// файл xnee_wrapper.h

// для создания указателя на сишную структуру
struct xnee_data;

class xnee_wrapper {
public:
    xnee_wrapper();
    ~xnee_wrapper();
    
private:
    xnee_wrapper(const xnee_wrapper& orig);
    xnee_wrapper& operator=(const xnee_wrapper& orig);
    xnee_data *xd; // вот этого указателя
};

При этом ругается на повторное определение:

error: using typedef-name ‘xnee_data’ after ‘struct’
/usr/include/libxnee/xnee.h:603: error: ‘xnee_data’ has a previous declaration here


Возможно, потому что тип структуры определен через typedef?
// файл /usr/include/libxnee/xnee.h
typedef struct{
...
} xnee_data;


Компилятор gcc version 4.4.1.
Re: Линковка сишной библиотеки в CPP
От: kpcb Россия  
Дата: 26.04.10 09:22
Оценка:
Здравствуйте, cpp_beginner, Вы писали:

_>Использую сишную библиотеку libxnee в проекте C++

_>Создаю класс обертки xnee_wrapper.
_>Подключаю хедеры в xnee_wrapper.h (перед всеми остальными хедерами)
_>[ccode]
_>extern "C"{
_>#include "libxnee/print.h"
_>#include "libxnee/xnee.h"
_>#include "libxnee/xnee_record.h"
_>#include "libxnee/xnee_grab.h"
_>#include "libxnee/xnee_alloc.h"
_>#include "libxnee/xnee_replay.h"
_>#include "libxnee/xnee_setget.h"
_>#include "libxnee/xnee_fake.h"
_>#include "libxnee/xnee_error.h"
_>#include "libxnee/xnee_session.h"
_>}

Посмотри, тебе точно надо включать _все_ хидеры, которые ты перечислил? Там скорее всего есть один-два которые надо оставить, а остальные убрать.
Re[2]: Линковка сишной библиотеки в CPP
От: cpp_beginner  
Дата: 26.04.10 09:34
Оценка:
Здравствуйте, kpcb, Вы писали:

K>Здравствуйте, cpp_beginner, Вы писали:


_>>Использую сишную библиотеку libxnee в проекте C++

_>>Создаю класс обертки xnee_wrapper.
_>>Подключаю хедеры в xnee_wrapper.h (перед всеми остальными хедерами)
_>>[ccode]
_>>extern "C"{
_>>#include "libxnee/print.h"
_>>#include "libxnee/xnee.h"
_>>#include "libxnee/xnee_record.h"
_>>#include "libxnee/xnee_grab.h"
_>>#include "libxnee/xnee_alloc.h"
_>>#include "libxnee/xnee_replay.h"
_>>#include "libxnee/xnee_setget.h"
_>>#include "libxnee/xnee_fake.h"
_>>#include "libxnee/xnee_error.h"
_>>#include "libxnee/xnee_session.h"
_>>}

K>Посмотри, тебе точно надо включать _все_ хидеры, которые ты перечислил? Там скорее всего есть один-два которые надо оставить, а остальные убрать.


Точно все. На редкость бестолковая библиотека, API разбросан по куче хедеров непонятно по какому признаку.
Re: Линковка сишной библиотеки в CPP
От: uzhas Ниоткуда  
Дата: 26.04.10 10:09
Оценка:
Здравствуйте, cpp_beginner, Вы писали:

_>Использую сишную библиотеку libxnee в проекте C++


_>Ругается на multiple definition

Странная у вас библиотека.
Вот фрагмент кода из xnee_internal.h
/* ** Do NOT edit ** */
enum _xnee_data_types {
  XNEE_EVENT  = 0,
  XNEE_REQUEST  ,
  XNEE_REPLY             ,
  XNEE_ERROR             ,
  XNEE_DELIVERED_EVENT   ,
  XNEE_DEVICE_EVENT      ,
  XNEE_EXT_REPLY_MAJOR   ,
  XNEE_EXT_REPLY_MINOR   ,
  XNEE_EXT_REQUEST_MAJOR ,
  XNEE_EXT_REQUEST_MINOR ,
  XNEE_NR_OF_TYPES       ,
  XNEE_META_DATA         ,
  XNEE_REPLAY_DATA       ,
  XNEE_SETTINGS_DATA     ,
  XNEE_MARK_DATA         ,
  XNEE_ACTION_DATA       ,
  XNEE_PRIMITIVE_DATA    ,
  XNEE_PROJECT_INFORMATION_DATA,
  XNEE_NEW_WINDOW_DATA,
  XNEE_NO_DATA          
} xnee_data_types ;

то есть тут определяется переменная xnee_data_types
сколько раз вы включите этот хедер — столько раз и будет определена эта переменная.
Отмечу, что так сделано для многих енумов и ни имя типа енума ни имя переменной не используют в коде (только константы из енмуа)
Зачем так делают — я не знаю. Не спец по сям =\ Подозреваю, что хотели сделать typedef.
Re[2]: Линковка сишной библиотеки в CPP
От: cpp_beginner  
Дата: 26.04.10 10:35
Оценка:
Здравствуйте, uzhas, Вы писали:

U>то есть тут определяется переменная xnee_data_types

U>сколько раз вы включите этот хедер — столько раз и будет определена эта переменная.
U>Отмечу, что так сделано для многих енумов и ни имя типа енума ни имя переменной не используют в коде (только константы из енмуа)
U>Зачем так делают — я не знаю. Не спец по сям =\ Подозреваю, что хотели сделать typedef.

Да, разобрался почему. Но пока непонятно как с этим бороться.
Понятно, можно включить сишные хедеры в единственном месте...
Re[2]: Линковка сишной библиотеки в CPP
От: cpp_beginner  
Дата: 26.04.10 15:05
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, cpp_beginner, Вы писали:


_>>
_>>// для создания указателя на сишную структуру
_>>extern "C" struct xnee_data;
_>>


Не помогает.

error: using typedef-name ‘xnee_data’ after ‘struct’

Re[2]: Линковка сишной библиотеки в CPP
От: uzhas Ниоткуда  
Дата: 26.04.10 15:37
Оценка:
Здравствуйте, Cyberax, Вы писали:

// для создания указателя на сишную структуру
struct xnee_data;


Нет такой структуры, поэтому не пишите struct xnee_data.
xnee_data — это синоним (typedef) для анонимной структуры.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.