2014-07-11 2 views
0

Проект построен на платформе Win32, но не на x64.LNK2001: неразрешенный внешний символ при построении платформы x64

Полное сообщение об ошибке: dllentry.obj: LNK2001 ошибка: неразрешенный внешний символ "класс CFactoryTemplate * g_Templates" (g_Templates @@ 3PAVCFactoryTemplate @@ A?)

dllentry.cpp компилирует на обеих платформах. Он содержит внешние объявления:

extern CFactoryTemplate g_Templates[]; 
extern int g_cTemplates; 

g_Templates [] затем используется в двух функциях:

__control_entrypoint(DllExport) STDAPI DllGetClassObject(__in REFCLSID rClsID, 
    __in REFIID riid, __deref_out void **pv) 
{ 
    ... 
    for (int i = 0; i < g_cTemplates; i++) 
    { 
     const CFactoryTemplate * pT = &g_Templates[i]; 
    } 
} 

и

DllInitClasses(BOOL bLoading) 
{ 
    ... 
    for (int i = 0; i < g_cTemplates; i++) 
    { 
     const CFactoryTemplate * pT = &g_Templates[i]; 
    } 
} 

Я проверил все библиотеки в настройках проекта и все кажется все в порядке, используются 64-битные версии. Что делать, чтобы сделать сборку проекта для платформы x64?

+2

Где определение (не объявление) g_Templates? Возможно ли, что файл был исключен из конфигурации x64? – dlf

+0

Чтобы найти проблему, попробуйте удалить 'extern' из строки' extern CFactoryTemplate g_Templates []; ' – KonstantinL

ответ

1

Вы заявили в комментарии к более раннему ответу

Другой, действительное определение, в myClass.cpp (основной класс моего проекта ) 'CFactoryTemplate * g_Templates = 0;' а затем 'int g_cTemplates = 0;' на самом верхнем уровне в файле, сразу после включения .

Ваше определение g_Templates не соответствует его заявлению.

Декларация является

extern CFactoryTemplate g_Templates[]; 

Объявляет g_Templates как массив CFactoryTemplate (неизвестного размера). Но ваше определение

CFactoryTemplates* g_Templates = 0; 

определяет его как указатель на CFactoryTemplate, что не то же самое.

Поэтому вам не удалось дать определение g_Templates, которое соответствует объявлению, и сообщение об ошибке верное.

Вам необходимо получить декларацию и определение, чтобы согласиться. Один из способов - написать

CFactoryTemplates g_Templates[1]; 

, чтобы создать определение, соответствующее декларации. (Обратите внимание, что нулевой длины массивов запрещены в C++, так что вместо этого мы создаем массив длины 1 и игнорировать элемент в нем.)

Другой изменить объявление в

extern CFactoryTemplates* g_Templates; 
+0

Массивы распадаются на указатели в объявлениях extern. Я тестировал с VC2012, и у него не было проблемы с соответствием 'extern int g []' с 'int * g' в другом модуле. – dlf

+0

Но, возможно, VC ошибочен, поскольку дальнейшее тестирование показывает, что, хотя компоновщик принимает это, два 'g' в конечном итоге становятся разными (и инспектор отладки очень запутан). – dlf

+2

@dff Массивы не распадаются на указатели в объявлениях extern. Они распадаются на указатели при преобразовании lvalue-rvalue и объявляются как параметры функции, но декларация не является ни одной. –

0

В заявлении extern CFactoryTemplate g_Templates[]; фактически не определяется массив * по названию g_Templates; он просто утверждает, что существует где-то в проекте. Вы, по сути, говорите компилятору: «Не беспокойтесь, что вы ничего не видите, когда придет время для ссылки, вы сможете найти его в другом модуле». За исключением того, что, по-видимому, это не так. Возможны две возможные причины: (1) Файл, содержащий фактическое определение g_Templates, не включается в конфигурацию сборки x64, и (2) определение, где бы оно ни было, окружено чем-то вроде #ifdef x86.

Чтобы решить эту проблему, вам необходимо найти фактическое определение g_Templates (возможно, найдите «CFactoryTemplate g_Templates ["), а затем определите, почему он не указан в сборке x64.


* Технически это трактуется как указатель здесь

+0

g_templates определен в sysclock.cpp, другом базовом классе DirectShow, но только в #ifdef FILTER_DLL, условии, которое не выполняется в Win32 ни. Другое, действительное определение, находится в myClass.cpp (основной класс моего проекта) 'CFactoryTemplate * g_Templates = 0;' за которым следует 'int g_cTemplates = 0;' на самом верхнем уровне в файле, сразу после включения. myClass.cpp также компилируется сам по себе. Только сборка не работает. –

+0

Из исходного кода я понимаю, что вы делаете dll, и там возникает ошибка ссылки. Является ли myClass.cpp включенным в эту DLL, или это в отдельный проект exe? – dlf

 Смежные вопросы

  • Нет связанных вопросов^_^