Мне трудно понять, почему я получаю неразрешенный внешний символ, когда пытаюсь создать программу. У меня 3 файла. Давайте скажем
main.cpp
file.cu
headerfile.h
У меня есть две константные переменные, определенные в моей основной функции в файле main.cpp
:
const uint N = 1048576;
const uint base = 1024;
Я также определил функции, необходимые в headerfile.h
:
template <const uint N, const uint base>
void F1(
float2 *d_S_x,
float2 *d_S_y,
bool *S_yy,
CCP *dev_CP,
uint batchSize,
uint batchLength
);
наряду с другими, такими как:
...
extern "C" uint bitonicSort(
float2 *d_P_out,
float2 *d_P_in,
uint batchSize,
uint arrayLength,
uint dir,
uint xy
);
...
Я должен использовать шаблоны, потому что переменные N
и base
будут использоваться при распределении разделяемой памяти на устройстве, поэтому мне нужно иметь константные переменные. Функция F1
похожа на функцию интерфейса в file.cu
откуда я буду запускать свои ядра. Теперь из main.cpp
я обычно вызываю F1
F1 <N,base> ( d_S_x, d_S_y, d_S_yy, dev_CP, batchsize, batchLength);
и я запускаю некоторые ядра из F1
(или другой функции, показанной по ошибке BF
), например:
MinReduction <N, base> <<< 1, base >>>(dev_CP);
Что-то не так с определениями функций в файле.h? Я думаю, что я что-то пропускаю с использованием extern вместе с шаблоном? Ошибки:
Error 4 error LNK1120: 2 unresolved externals E:\D....exe
Error 3 error LNK2001: unresolved external symbol "void __cdecl BF<1048576,1024>(struct float2 *,struct CCP *)" (??$BruteForce@$0BAAAAA@$0EAA@@@YAXPAUfloat2@@PAUCCP@@@Z) E:\...main.obj
Error 2 error LNK2001: unresolved external symbol "void __cdecl F1<1048576,1024>(struct float2 *,struct float2 *,bool *,struct CCP *,unsigned int,unsigned int)" (??$closest_pair@$0BAAAAA@$0EAA@@@YAXPAUfloat2@@0PA_NPAUCCP@@II@Z) E:\..main.obj
Где я должен определять функции, если не в headerfile.h
? Я понимаю, что Extern сообщает компилятору, что вы не объявляете новую переменную, а ссылаетесь на переменную, объявленную в другом месте. Но определение extern вместе с шаблоном не работает правильно? Любая помощь будет оценена по достоинству. Заранее спасибо.
Все явные объявления специализации должны быть видны во время создания шаблона.
С вашего (неполного) сообщения кажется, что у вас есть следующий (упрощенный) сценарий:
main.cu file
const int N = 1048576;
const int base = 1024;
#include "test.cuh"
int main() {
F1<N,base>();
return 0;
}
test.cuh file
template<const int N, const int base> void F1();
test.cu file
template<int N, int base> void F1() { }
Эта структура даст следующее сообщение об ошибке
error LNK2001: unresolved external symbol "void __cdecl F1<1048576,1024>(void)" (??$F1@$0BAAAAA@$0EAA@@@YAXXZ)
Причина в том, что неявная специализация, возникающая в вызове F1<N,base>
в файле main.cu
не отображается в трансляционной единице, где определен F1
(файл test.cu
).
Вы должны использовать что-то вроде
const int N = 1048576;
const int base = 1024;
template<int N, int base> void F1() { };
int main() {
F1<N,base>();
return 0;
}
В этом случае неявная специализация F1<N,base>();
происходящих в файле main.cu
происходит в том же самом main.cu
модуле, где F1
определен.
Ваш вопрос не связан с CUDA и является проблемой использования шаблонов в C++. Вы можете ознакомиться с этим руководством для получения более подробной информации.
headerfile.h
а не переопределять или объявлять его в файле main.cpp. Я также читаю руководство, которое вы упомянули. :)
Хотя ответ JackOLantern вполне уместен, позвольте быть немного более специфичным для CUDA: интересно, действительно ли вам нужны эти две переменные шаблона.
Таким образом, вы можете создать проблему для себя... (или вы не можете, но другие в вашей ситуации вполне могут это сделать).
headerfile.h
. Не беспокойтесь о значениях N и базы. Они не меняются на протяжении всей программы. Я уже определил их как постоянные.
file.cu
переводаfile.cu
но не в основном файле, либо они пропускают объявление шаблона там, где оно выполняется.