如何在多个.cpp和.cu文件之间分割类定义
How to split class definition between multiple .cpp and .cu files?
我有一个类嵌套类混合c++, CUDA和Thrust。我想把成员定义拆分到多个文件中。
// In cls.h:
#include <thrust/device_vector.h>
class cls {
class foo { // define in foo.cu (include "cls.h")
kernelWrapper();
}
class bar { // define in bar.cu (include "cls.h")
thrust::device_vector A;
thrustStuff();
}
thrust::device_vector B;
pureCPP(); // define in cls.cpp (include "cls.h")
moreThrust(); // define in cls.cu (include "cls.h")
}
在每个定义文件中,我只是#include "cls.h"
。然而,无论我尝试什么,我目前都得到各种各样的编译器错误,如pureCPP was referenced but not defined
。
我读过推力只能与
.cu
文件一起使用。因为我的父类cls
声明像B
这样的推力类型变量(因此#include
和thrust/device_vector.h
),这是否强制所有#include
cls.h
的文件被制作成.cu
文件?在这种情况下我在哪里使用
extern "C"
?我想cls.cpp
会要求.cu
文件中的所有函数都包装在extern "C"
中,但是.cu
到.cu
调用如何,比如moreThrust()
调用bar::thrustStuff()
我也知道类的成员不与
extern "C"
工作,所以我必须为每个成员函数写一个extern "C"
包装器函数吗?
我完全困惑于如何使这一切工作- #include
s和extern "C"
s的鸡尾酒我需要每个文件?
以您的小示例为例,这对我来说编译和运行良好
/*
Inside File cls.h
*/
#pragma once
#include <thrust/device_vector.h>
#include <stdio.h>
class cls {
public:
class foo { // define in foo.cu (include "cls.h")
public:
void kernelWrapper();
};
class bar { // define in bar.cu (include "cls.h")
thrust::device_vector<int> A;
public:
void thrustStuff();
};
public:
void pureCPP(); // define in cls.cpp (include "cls.h")
void moreThrust(); // define in cls.cu (include "cls.h")
private:
thrust::device_vector<int> B;
};
/*
Inside File foo.cu
*/
#include "cls.h"
void cls::foo::kernelWrapper()
{
printf("kernelWrappern");
}
/*
Inside File bar.cu
*/
#include "cls.h"
void cls::bar::thrustStuff()
{
printf("Thrust Stuffn");
}
/*
Inside File cls.cpp
*/
#include "cls.h"
void cls::pureCPP()
{
printf("pureCPPn");
}
/*
Inside File cls.cu
*/
#include "cls.h"
void cls::moreThrust()
{
printf("moreThrustn");
}
/*
Inside File main.cpp
*/
#include "cls.h"
int main()
{
cls a_class;
a_class.pureCPP();
a_class.moreThrust();
cls::bar a_class_bar;
a_class_bar.thrustStuff();
cls::foo a_class_foo;
a_class_foo.kernelWrapper();
}
运行此命令打印
pureCPP
moreThrust
Thrust Stuff
KernelWrapper
如果有的话,我打赌你正在使用一个IDE,它没有编译你所有的文件,所以当你在你的头文件中有你的类成员声明,但它永远不会找到相应的定义。您确切的编译命令可能会有所不同,但对于我(在Linux上),我使用
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/bar.d" "../src/bar.cu"
nvcc --device-c -G -O0 -g -gencode arch=compute_20,code=sm_21 -x cu -o "src/bar.o" "../src/bar.cu"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/cls.d" "../src/cls.cu"
nvcc --device-c -G -O0 -g -gencode arch=compute_20,code=sm_21 -x cu -o "src/cls.o" "../src/cls.cu"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/foo.d" "../src/foo.cu"
nvcc --device-c -G -O0 -g -gencode arch=compute_20,code=sm_21 -x cu -o "src/foo.o" "../src/foo.cu"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/main.d" "../src/main.cpp"
nvcc -G -g -O0 --compile -x c++ -o "src/main.o" "../src/main.cpp"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/clscpp.d" "../src/cls.cpp"
nvcc -G -g -O0 --compile -x c++ -o "src/clscpp.o" "../src/cls.cpp"
nvcc --relocatable-device-code=true -gencode arch=compute_20,code=sm_21 -link -o "split_compilation" ./src/bar.o ./src/cls.o ./src/foo.o ./src/clscpp.o ./src/main.o
这个想法只是编译所有的源文件并将它们链接在一起。例如,如果我没有编译和链接cls.cpp文件,我将在任何调用pureCPP
时获得链接器错误。
另外,请注意,如果您使用实际的设备代码,则必须为您的成员函数指定__device__
和/或__host__
。参见这个SO问题
- 如何在cpp文件之间切换窗口?在Qt中
- 如何使用管道在父级和子级之间来回传递文件
- 共享库 (.so) 没有扩展名的 Linux 可执行文件之间的区别?
- 在.cpp文件之间传递结构声明,而不使用全局头文件
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 在.cpp文件之间传递全局字符串变量?
- 如何在 的开头<x>和结尾<y>之间更改带有文件输出的字符串的值
- 在两个.cpp文件之间定义全局类/结构指针
- 文件删除(使用取消链接)与释放所有磁盘空间之间的延迟
- CSV文件之间的差异,使用getline()产生不同的结果
- 检测到 Conan 配置文件设置与 CMake 之间的编译器版本不匹配
- 如何从txt文件c++中提取括号之间的数字
- 包括两个文件 C++ 之间的冲突
- 在没有外部文件的情况下在应用会话之间保存变量
- 如何读取特定单词之间的文本文件?
- OpenCV 文件存储 - 错误:元素之间的解析错误 (icvYMLParseValue) 缺失
- 为什么 .cpp 文件和 .h 文件之间有区别?
- 在结构函数之间传递文件路径 C++ 编辑:修复LNK2019错误
- 在头文件和 .cc 文件之间建立关系
- CPP项目中.fdf和.h文件之间的差异