dllexport'ing неполный класс - PullRequest
0 голосов
/ 06 января 2011

[РЕДАКТИРОВАТЬ: дальнейшее копание выявило другую корневую проблему. Я перефразирую вопрос, но оставляю старую версию ниже для согласованности с ответом @Leo]

Кажется, что VC ++ (как в VS2005, так и в VS2010) позволяет мне использовать классы с отсутствующими реализациями! Следующий код строит нормально:

// missingimp.h :
class __declspec(dllexport) MissingImp
{
  void DoStuff();   // no implementation anywhere
  void DoMoreStuff();  // neither for this
}

// missingimp.cpp
#include "missingimp.h"

Код прекрасно компилируется и связывается (в конфигурации dll) - и, конечно, статическое соединение с полученным dll не выполняется. Это ошибка? это поведение как-то по замыслу ??

[Старый вопрос:]

Я пытаюсь выполнить dlex для класса, в котором есть член данных, заданный в объявленном заранее типе:

// Class2Export.h:

class ForwardDeclared ;

template<class T> class TemplatedClass
{
T *m_ptr;

public:
TemplatedClass() { m_ptr->DoSomething(); }

};

class __declspec(dllexport) ExportedClass
{
TemplatedClass<ForwardDeclared> TemplateForward;
};

// Class2Export.cpp:

#include "Class2Export.h"

(Это не надуманный пример - в реальном коде TemplatedClass - это умный указатель, но он не имеет отношения к рассматриваемой проблеме.)

Этот код не компилируется, с -

ошибка C2027: использование неопределенного типа 'ForwardDeclared'

Это все еще имеет какой-то смысл, основываясь на ответе от MS :

Если у TemplatedClass есть конструктор тогда конструктор будет автоматически генерируется для ExportedClass. Поскольку ExportedClass является экспортируется компилятор пытается экспортировать конструктор, но не может генерировать код для этого, потому что ForwardDeclared является неизвестно.

Но я подозреваю, что это не окончательный ответ, как, когда я объявляю (даже не реализуя!) Ctor для ExportedClass:

...
class __declspec(dllexport) ExportedClass
{
ExportedClass();
TemplatedClass<ForwardDeclared> TemplateForward;
};
...

и компиляция и ссылка завершаются успешно (с должным предупреждением *). Проблема в MS-Connect кажется заброшенной - может быть, кто-нибудь может пролить свет на это странное поведение?

Спасибо!

* РЕДАКТИРОВАТЬ: сгенерированное предупреждение C4251 : Класс «TemplatedClass» должен иметь dll-интерфейс для использования клиентами класса «ExportedClass»

Ответы [ 2 ]

1 голос
/ 06 января 2011

Если у меня неправильный конец флешки, проблема заключается в том, когда генерируется код конструктора ExportedClass.

Если код конструктора ExportedClass генерируется до того, как объявлен ForwardDeclared (не объявлен заранее, ноправильно объявлено), тогда вы получите ошибку, так как конструктор ExportedClass неявно вызывает конструктор TemplatedClass, который вызывает метод ForwardDeclared, который не определен.

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

Если выизмените ваш последний пример на этот, вы должны снова получить ошибки: (Все, что добавлено, это две фигурные скобки, чтобы дать конструктору ExportedClass пустое тело)

class __declspec(dllexport) ExportedClass
{
    ExportedClass() { } // Error here
    TemplatedClass<ForwardDeclared> TemplateForward;
};

И этот код - то, что вы неявно делаете, если вывообще не имеет конструктора для ExportedClass.В этих случаях код конструктора тут же генерируется в заголовочном файле.С другой стороны, когда конструктор объявляется без тела в заголовке, вы оставляете код, который будет определен и сгенерирован где-то еще.

0 голосов
/ 16 января 2011

В конце концов я нашел ответ на форумах MS .

Я делаю ссылку на него здесь, на случай, если он кому-нибудь пригодится.

...