使用#define宏标准化类声明 我正在为我的一个项目构建一个C++ DLL。我试图标准化类的定义方式。因此,不要每次都写: class __declspec(dllexport) ClassName
我正在构建一个使用#define宏标准化类声明 我正在为我的一个项目构建一个C++ DLL。我试图标准化类的定义方式。因此,不要每次都写: class __declspec(dllexport) ClassName,c++,class,c-preprocessor,C++,Class,C Preprocessor,我正在构建一个#define宏以简化此过程: #define CLASS( cName ) class __declspec(dllexport) cName 但是,当我使用它时,它会给我以下错误: Error: Expected a ';' 我知道您可以使用#define宏来定义整个类创建,但它可以仅用于定义“类头”吗 谢谢 请记住,我之所以这么做是因为我们将要处理数百个类,所以这些类型的“自动化”将非常有用:) 编辑: 例如: #define CLASS( nClass ) class
#define
宏以简化此过程:
#define CLASS( cName ) class __declspec(dllexport) cName
但是,当我使用它时,它会给我以下错误:
Error: Expected a ';'
我知道您可以使用#define
宏来定义整个类创建,但它可以仅用于定义“类头”吗
谢谢
请记住,我之所以这么做是因为我们将要处理数百个类,所以这些类型的“自动化”将非常有用:)
编辑:
例如:
#define CLASS( nClass ) class __declspec(dllexport) nClass
CLASS( APTest )
{ // Here is the error of missing ';'
public:
APTest();
};
不要这样做
C++已经标准化了
如果你希望别人读你的代码,那就用传统的C++写,而不是一些看起来不同的老式方言。习惯了正确的C++语法,它将更容易阅读别人的C++代码。
一件有意义的事情是简化\u declspec
部分,您可以这样做:
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
class DLLEXPORT APTest
{
// ...
};
#ifdef MYLIB_DLL
#ifndef MYLIB_IFACE
#ifdef MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllexport )
#else // !MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllimport )
#endif // !MYLIB_IFACE_EXPORT
#endif // !MYLIB_IFACE
#else // !MYLIB_DLL
#ifndef MYLIB_IFACE
#define MYLIB_IFACE
#endif // !MYLIB_IFACE
class MYLIB_IFACE MyClass
{
};
void MYLIB_IFACE myFunc();
#ifdef WIN32
#define KX_SYMBOL_EXPORT _declspec( dllexport )
#define KX_SYMBOL_IMPORT _declspec( dllimport )
#else // GCC
#define KX_SYMBOL_EXPORT __attribute__(( visibility ("default")))
#define KX_SYMBOL_IMPORT
#endif
#ifdef KX_DLL
#ifndef KX_IFACE
#ifdef KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_EXPORT
#else // !KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_IMPORT
#endif // !KX_IFACE_EXPORT
#endif // !KX_IFACE
#else // !KX_DLL
#ifndef KX_IFACE
#define KX_IFACE
#endif // !KX_IFACE
#endif // !KX_DLL
编写
CLASS(APTest)
并没有让你的生活变得更简单,反而让别人更难理解。只要说不。有一个比“清醒”更好的方法。这样做:
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
class DLLEXPORT APTest
{
// ...
};
#ifdef MYLIB_DLL
#ifndef MYLIB_IFACE
#ifdef MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllexport )
#else // !MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllimport )
#endif // !MYLIB_IFACE_EXPORT
#endif // !MYLIB_IFACE
#else // !MYLIB_DLL
#ifndef MYLIB_IFACE
#define MYLIB_IFACE
#endif // !MYLIB_IFACE
class MYLIB_IFACE MyClass
{
};
void MYLIB_IFACE myFunc();
#ifdef WIN32
#define KX_SYMBOL_EXPORT _declspec( dllexport )
#define KX_SYMBOL_IMPORT _declspec( dllimport )
#else // GCC
#define KX_SYMBOL_EXPORT __attribute__(( visibility ("default")))
#define KX_SYMBOL_IMPORT
#endif
#ifdef KX_DLL
#ifndef KX_IFACE
#ifdef KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_EXPORT
#else // !KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_IMPORT
#endif // !KX_IFACE_EXPORT
#endif // !KX_IFACE
#else // !KX_DLL
#ifndef KX_IFACE
#define KX_IFACE
#endif // !KX_IFACE
#endif // !KX_DLL
将这样的块放入dll中每个文件使用的头中,并放入dll的公共头中
应从dll中导出的每个符号都会按如下方式进行标记:
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
class DLLEXPORT APTest
{
// ...
};
#ifdef MYLIB_DLL
#ifndef MYLIB_IFACE
#ifdef MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllexport )
#else // !MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllimport )
#endif // !MYLIB_IFACE_EXPORT
#endif // !MYLIB_IFACE
#else // !MYLIB_DLL
#ifndef MYLIB_IFACE
#define MYLIB_IFACE
#endif // !MYLIB_IFACE
class MYLIB_IFACE MyClass
{
};
void MYLIB_IFACE myFunc();
#ifdef WIN32
#define KX_SYMBOL_EXPORT _declspec( dllexport )
#define KX_SYMBOL_IMPORT _declspec( dllimport )
#else // GCC
#define KX_SYMBOL_EXPORT __attribute__(( visibility ("default")))
#define KX_SYMBOL_IMPORT
#endif
#ifdef KX_DLL
#ifndef KX_IFACE
#ifdef KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_EXPORT
#else // !KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_IMPORT
#endif // !KX_IFACE_EXPORT
#endif // !KX_IFACE
#else // !KX_DLL
#ifndef KX_IFACE
#define KX_IFACE
#endif // !KX_IFACE
#endif // !KX_DLL
然后,在dll中的每个.cpp文件中,第一行应该是:
#define MYLIB_IFACE_EXPORT
如果您这样做,那么它将在不使用dllexport/dllimport的POSIX系统上正常构建。要构建库的dll版本,请定义MYLIB_dll。(您可以在编译器的标志中执行此操作,以便可以从生成系统控制它)
要构建库的静态版本,请不要定义MYLIB_DLL
@更新:
您可以将其扩展为支持GCC可视性,如下所示:
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
class DLLEXPORT APTest
{
// ...
};
#ifdef MYLIB_DLL
#ifndef MYLIB_IFACE
#ifdef MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllexport )
#else // !MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllimport )
#endif // !MYLIB_IFACE_EXPORT
#endif // !MYLIB_IFACE
#else // !MYLIB_DLL
#ifndef MYLIB_IFACE
#define MYLIB_IFACE
#endif // !MYLIB_IFACE
class MYLIB_IFACE MyClass
{
};
void MYLIB_IFACE myFunc();
#ifdef WIN32
#define KX_SYMBOL_EXPORT _declspec( dllexport )
#define KX_SYMBOL_IMPORT _declspec( dllimport )
#else // GCC
#define KX_SYMBOL_EXPORT __attribute__(( visibility ("default")))
#define KX_SYMBOL_IMPORT
#endif
#ifdef KX_DLL
#ifndef KX_IFACE
#ifdef KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_EXPORT
#else // !KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_IMPORT
#endif // !KX_IFACE_EXPORT
#endif // !KX_IFACE
#else // !KX_DLL
#ifndef KX_IFACE
#define KX_IFACE
#endif // !KX_IFACE
#endif // !KX_DLL
为了简单起见,我删除了第一个示例中的GCC位。但这是一个真正的方法@Wakely非常正确。在宏调用之前或之后出现语法错误。在看不到更多上下文的情况下,无法准确说出具体内容。能否举例说明如何使用此
类
宏?也许这是一个简单的使用错误?您能在这个用法上面显示代码吗?在该文件中#define
之前是什么?如果没有,那么在其他文件中包含该文件的地方会出现什么?如果您使用的是gcc,请尝试使用选项-E运行它,它将向您显示编译器在预处理之后是如何查看代码的。。。其实很有道理。我实际上是想简化这个u declspec(dllexport)命令。谢谢你的建议!MYLIB\u DLL\u EXPORT应该是MYLIB\u IFACE\u EXPORT还是反之?为了增加好处,可以使用GCC的属性在一些POSIX平台上实现类似的效果。对于添加的属性,您应该使用可见性属性。为了简单起见,我从我的生产代码中删去了它。关于MYLIB\u DLL\u导出,请再次访问。固定的。