Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用#define宏标准化类声明 我正在为我的一个项目构建一个C++ DLL。我试图标准化类的定义方式。因此,不要每次都写: class __declspec(dllexport) ClassName_C++_Class_C Preprocessor - Fatal编程技术网

使用#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导出,请再次访问。固定的。