crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Предварительное объявление класса, Проблема при объявлении пользовательского типа
Snake174
  опции профиля:
сообщение 17.8.2012, 15:01
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 89
Регистрация: 18.4.2011
Из: Миасс
Пользователь №: 2613

Спасибо сказали: 9 раз(а)




Репутация:   0  


Всем привет.
Ситуация такая: пишу динамическую библиотеку. Нужно чтобы в конечном итоге получилось 2 файла (сама библиотека и заголовочный файл с объявлением функций).

Заголовочный файл:
#ifndef HEADER_H
#define HEADER_H

#ifdef WIN32
  #include <windows.h>
  #define EXPORT __declspec(dllexport)
#else
  #define EXPORT __attribute__((visibility("default")))
#endif

EXPORT Object *GetObject();

#endif // HEADER_H


Исходник:
#include "header.h"
#include "object.h"

#ifdef WIN32
BOOL WINAPI DllMain( HINSTANCE /*hinstDLL*/, DWORD /*fdwReason*/, LPVOID /*lpvReserved*/ )
{
  return TRUE;
}
#endif

Object *GetObject()
{
  return pObject.GetObject();
}


object.h
class Object
{
  public:
    Object();
    Object *GetObject();
};

extern Object pObject;


object.cpp
Object::Object
{
}

Object *Object::GetObject()
{
  Object *obj = new Object();
  return obj;
}

Object pObject;


Вопрос такой: можно как-нибудь в файле header.h указать тип Object без включения в него object.h? Не хотелось бы таскать вместе с библиотекой эти файлы.
Если в header.h прописать class Object, то при вызове в программе, к которой линкуется данная библиотека, выходит ошибка forward declaration и uninizialized struct Object.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 17.8.2012, 15:49
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Используй forward declaration:
#ifndef HEADER_H
#define HEADER_H

#ifdef WIN32
  #include <windows.h>
  #define EXPORT __declspec(dllexport)
#else
  #define EXPORT __attribute__((visibility("default")))
#endif

class Object;

EXPORT Object *GetObject();

#endif // HEADER_H
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 17.8.2012, 16:49
Сообщение #3


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


В вашем случае такой вариант не прокатит, т.к. в публичном интерфейсе вы возвращаете объект, который не собираетесь поставлять. Необходимо экспортировать класс Object и его заголовок тоже таскать.

примерно так:
class EXPORT Object
{
  public:
    Object();
    Object *GetObject();
};

extern EXPORT Object pObject;
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 17.8.2012, 20:09
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1592
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 218 раз(а)




Репутация:   12  


если интерфейс библиотеки работает с классом, то без объявления этого класса компилятор с ним работать не сможет. ему нужно как-то генерить информацию об объекте. так что описание класса всегда должно присутствовать в заголовочниках.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Snake174
  опции профиля:
сообщение 20.8.2012, 4:21
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 89
Регистрация: 18.4.2011
Из: Миасс
Пользователь №: 2613

Спасибо сказали: 9 раз(а)




Репутация:   0  


Спасибо всем за разъяснения.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 20.8.2012, 13:11
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Цитата(wiz29 @ 17.8.2012, 17:49) *
В вашем случае такой вариант не прокатит, т.к. в публичном интерфейсе вы возвращаете объект, который не собираетесь поставлять. Необходимо экспортировать класс Object и его заголовок тоже таскать.

Вот тут есть нюанс: если в публичном интерфейсе функция должна возвращать не объект, а только лишь указатель на него, то forward declarartion как раз и позволит "развязать" заголовки. Другое дело, что, даже имея указатель, но не имея описания самого класса, - нельзя будет обратиться к членам этого класса (дернуть там метод, или обратиться к полю...). Вот тут - придется всяко включать заголовок этого класса.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 21.8.2012, 15:40
Сообщение #7


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Цитата(Влад @ 20.8.2012, 14:11) *
Вот тут есть нюанс: если в публичном интерфейсе функция должна возвращать не объект, а только лишь указатель на него, то forward declarartion как раз и позволит "развязать" заголовки.


Ну и что с этим указателем дальше делать?:) Проверить на ноль и успокоиться?:)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 12.11.2019, 11:21