CLI / C ++ ссылка ошибка 2028 и 2019 - PullRequest
1 голос
/ 13 апреля 2011

У меня проблема с передачей шаблонов (я думаю, что причина) из проекта CLI.

У меня есть 3 уровня классов (по причинам инкапсуляции и техническим причинам).

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

Класс A находится в C ++ DLL:

class A {
public:
    template<class T>
    void foo(T blah) { //Do stuff }
}

Класс B Обертывание класса A (также обычный класс без ссылки):

class B {
public:
    template<class T>
    void foo(T blah) { a->foo(blah); }
private:
    A* a;
}

Класс C - это класс ref, который вызывает класс B с явным типом:

ref class C {
public:
    void foo(int blah) { b->foo(blah); }
private:
    B* b;
}

Они хорошо компилируются (создан .obj), но компоновщик неправильно связывает объекты.

Я получаю 2 ошибки компоновщика для метода:

ошибка LNK2028: неразрешенный токен (0A000645) "public: void __cdecl B :: foo (class utils :: CustomString const &, int const &) " (?? $ Foo @ _N @ B @ пространство имен @@ $$ FQEAAXAEBVCustomString @ @@ Utils AEB_N @ Z) упоминается в функции "private: void" __clrcall C :: foo (int) "(?? $ foo @ _N @ Пространство имен @@ $$ FAE $ AAMXPE $ AAVString @ System @@ _ N @ Z) * ​​1029 *

ошибка LNK2019: неразрешенная внешняя ошибка символа LNK2019: не устранена внешний символ "public: void __cdecl B :: foo (класс int const &) " ?? $ Foo @ _N @ B @ пространство имен @@ $$ FQEAAXAEBVCustomString @ @@ Utils AEB_N @ Z) упоминается в функции "private: void" __clrcall C :: foo (int) "(?? $ foo @ _N @ Namespace @@ $$ FAE $ AAMXPE $ AAVString @ System @@ _ N @ Z) * ​​1031 *

Редактировать

У меня нет линий со мной (не на том же ПК), но он говорит, что не может связать B.foo , на который ссылается C.foo

Я компилирую класс ref с помощью / clr в режиме отладки / MDd (да, он должен быть в режиме отладки из-за других зависимостей, которые все скомпилированы одинаково )

Кто-нибудь знает, почему это происходит? И еще важнее: как это решить?

Edit:

При настройке класса B (оболочки) для компиляции с / GL (оптимизация всей программы) я получаю другую ошибку:
LNK2001

ошибка LNK2001: не устранена внешний символ "public: bool __cdecl Интерфейс :: B :: foo (int &) const " (?? $ foo @ _J @ B @ Пространство имен @@ $$ FQEBA_NAEBVCustomString @ 123 @ AEA_J @ Z) * ​​1062 *

Ответы [ 3 ]

1 голос
/ 01 мая 2011

Проблема заключается в ошибке компоновщика Visual Studio.

Прежде всего, вам необходимо установить флаг / GL (Whole Program Optimization) , чтобы он связывал шаблон после компиляции.

Затем необходимо использовать один из следующих обходных путей:

BUG: LNK2001 в функции-члене при использовании шаблона вложенного класса

0 голосов
/ 13 апреля 2011

Это стандартная потеря для шаблонов C ++, у них нет внешних связей, таких как .NET generics. Вы должны поместить определение функции шаблона в файл заголовка, чтобы вы могли #include его в файле исходного кода, который содержит класс ref. Точно так же, как ваш фрагмент кода. Это не относится к C ++ / CLI.

Обязательно оберните #include управляемой #pragma, если вы компилируете остальные нативные классы без параметра / clr (как вы должны). Как это:

#pragma managed(push, off)
#include "FileWithTemplateDefinition.h"
#pragma managed(pop)
0 голосов
/ 13 апреля 2011

Эти ошибки компоновщика указывают на то, что вы где-то упускаете определение (в отличие от объявления). Отсутствие доступа к вашему коду затрудняет нам это определение, особенно без каких-либо подробных ошибок компоновщика.

[EDIT]

Этот код прекрасно компилируется и связывается для меня в управляемом проекте C ++:

#pragma managed

class A {
public:
    template<class T>
    void foo(T blah) { int i = 0; }
};

//Class B wraps class A (also regular non-ref class):
class B {
public:
    template<class T>
    void foo(T blah) { a.foo(blah); }
private:
    A a;
};

// Class C is a ref class, which calls class B with an explicit type :
ref class C {
public:
    C() { b = new B(); }
    ~C() {  }
    !C() { delete b; }
    void foo(int blah) { b->foo(blah); }
private:
    B* b;
};
...