class C++ 中的声明
class declaration in C++
我有一个 Class :
class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface { ... };
RTC_EXPORT 定义为
#ifndef RTC_BASE_SYSTEM_RTC_EXPORT_H_
#define RTC_BASE_SYSTEM_RTC_EXPORT_H_
// RTC_EXPORT is used to mark symbols as exported or imported when WebRTC is
// built or used as a shared library.
// When WebRTC is built as a static library the RTC_EXPORT macro expands to
// nothing.
#ifdef WEBRTC_ENABLE_SYMBOL_EXPORT
#ifdef WEBRTC_WIN
#ifdef WEBRTC_LIBRARY_IMPL
#define RTC_EXPORT __declspec(dllexport)
#else
#define RTC_EXPORT __declspec(dllimport)
#endif
#else // WEBRTC_WIN
#if __has_attribute(visibility) && defined(WEBRTC_LIBRARY_IMPL)
#define RTC_EXPORT __attribute__((visibility("default")))
#endif
#endif // WEBRTC_WIN
#endif // WEBRTC_ENABLE_SYMBOL_EXPORT
#ifndef RTC_EXPORT
#define RTC_EXPORT
#endif
#endif // RTC_BASE_SYSTEM_RTC_EXPORT_H_
class RTC_EXPORT PeerConnectionInterface :public rtc::RefCountInterface {...};
中的 RTC_EXPORT 是做什么的?
通常我们在c++中将类定义为class Myclass{...}
。额外的MACRO一般有什么作用?
宏在您的代码段中定义:
#ifdef WEBRTC_LIBRARY_IMPL
#define RTC_EXPORT __declspec(dllexport)
#else
#define RTC_EXPORT __declspec(dllimport)
#endif
这允许对动态库和调用者代码使用相同的 class 声明。
The dllexport and dllimport storage-class attributes are
Microsoft-specific extensions to the C and C++ languages. You can use
them to export and import functions, data, and objects to or from a
DLL.
https://docs.microsoft.com/en-us/cpp/cpp/dllexport-dllimport?view=vs-2019
除了 Dmitry 的回答之外,我还想添加一些实用工具来检查 __declspec()
的影响。考虑以下源文件:
// library.cpp
__declspec(dllexport) int func(int x) { return 2 * x; }
从您的 Visual Studio 安装开始本机工具命令提示符
菜单。在那里,您可以使用以下命令将 link library.cpp
编译为 DLL:
> cd <Directory containing library.cpp>
> cl /c library.cpp
> link library.obj /DLL /NOENTRY
library.cpp
旁边应该有一个新创建的 library.dll
。以下命令检查导出的符号:
> dumpbin /EXPORTS library.dll
您应该会看到以下内容:
Dump of file library.dll
File Type: DLL
Section contains the following exports for library.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001000 ?func@@YAHH@Z
如您所见,library.dll
导出函数 ?func@@YAHH@Z
,这是 C++ 内部命名函数 func
的方式。如果省略 __declspec(dllexport)
,您将看不到此导出。同样,只有用 __declspec(dllexport)
注释的 class 才会导出其所有成员函数。
总结: 为了从 DLL 导出一个函数,你必须用 __declspec(dllexport)
.
注释它
现在,从 DLL 导出 classes 的常用方法是在 header:
中定义这样一个 #ifdef
开关
// header.h
#pragma once
#ifdef BUILD_LIBRARY
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
EXPORT int func(int x);
在库的源代码中,您定义了这个神奇的宏 BUILD_LIBRARY
:
// library.cpp
#define BUILD_LIBRARY
#include "header.h"
int func(int x) { return 2 * x; }
因此该函数将从您的库中导出。 DLL 的使用者将包括 header.h
但不应定义 BUILD_LIBRARY
:
#include "header.h"
#include <iostream>
int main() {
std::cout << func(10) << std::endl;
return 0;
}
由于此编译单元未定义 BUILD_LIBRARY
,因此 EXPORT
宏等于 __declspec(dllimport)
。
我有一个 Class :
class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface { ... };
RTC_EXPORT 定义为
#ifndef RTC_BASE_SYSTEM_RTC_EXPORT_H_
#define RTC_BASE_SYSTEM_RTC_EXPORT_H_
// RTC_EXPORT is used to mark symbols as exported or imported when WebRTC is
// built or used as a shared library.
// When WebRTC is built as a static library the RTC_EXPORT macro expands to
// nothing.
#ifdef WEBRTC_ENABLE_SYMBOL_EXPORT
#ifdef WEBRTC_WIN
#ifdef WEBRTC_LIBRARY_IMPL
#define RTC_EXPORT __declspec(dllexport)
#else
#define RTC_EXPORT __declspec(dllimport)
#endif
#else // WEBRTC_WIN
#if __has_attribute(visibility) && defined(WEBRTC_LIBRARY_IMPL)
#define RTC_EXPORT __attribute__((visibility("default")))
#endif
#endif // WEBRTC_WIN
#endif // WEBRTC_ENABLE_SYMBOL_EXPORT
#ifndef RTC_EXPORT
#define RTC_EXPORT
#endif
#endif // RTC_BASE_SYSTEM_RTC_EXPORT_H_
class RTC_EXPORT PeerConnectionInterface :public rtc::RefCountInterface {...};
中的 RTC_EXPORT 是做什么的?
通常我们在c++中将类定义为class Myclass{...}
。额外的MACRO一般有什么作用?
宏在您的代码段中定义:
#ifdef WEBRTC_LIBRARY_IMPL
#define RTC_EXPORT __declspec(dllexport)
#else
#define RTC_EXPORT __declspec(dllimport)
#endif
这允许对动态库和调用者代码使用相同的 class 声明。
The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. You can use them to export and import functions, data, and objects to or from a DLL.
https://docs.microsoft.com/en-us/cpp/cpp/dllexport-dllimport?view=vs-2019
除了 Dmitry 的回答之外,我还想添加一些实用工具来检查 __declspec()
的影响。考虑以下源文件:
// library.cpp
__declspec(dllexport) int func(int x) { return 2 * x; }
从您的 Visual Studio 安装开始本机工具命令提示符
菜单。在那里,您可以使用以下命令将 link library.cpp
编译为 DLL:
> cd <Directory containing library.cpp>
> cl /c library.cpp
> link library.obj /DLL /NOENTRY
library.cpp
旁边应该有一个新创建的 library.dll
。以下命令检查导出的符号:
> dumpbin /EXPORTS library.dll
您应该会看到以下内容:
Dump of file library.dll
File Type: DLL
Section contains the following exports for library.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001000 ?func@@YAHH@Z
如您所见,library.dll
导出函数 ?func@@YAHH@Z
,这是 C++ 内部命名函数 func
的方式。如果省略 __declspec(dllexport)
,您将看不到此导出。同样,只有用 __declspec(dllexport)
注释的 class 才会导出其所有成员函数。
总结: 为了从 DLL 导出一个函数,你必须用 __declspec(dllexport)
.
现在,从 DLL 导出 classes 的常用方法是在 header:
中定义这样一个#ifdef
开关
// header.h
#pragma once
#ifdef BUILD_LIBRARY
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
EXPORT int func(int x);
在库的源代码中,您定义了这个神奇的宏 BUILD_LIBRARY
:
// library.cpp
#define BUILD_LIBRARY
#include "header.h"
int func(int x) { return 2 * x; }
因此该函数将从您的库中导出。 DLL 的使用者将包括 header.h
但不应定义 BUILD_LIBRARY
:
#include "header.h"
#include <iostream>
int main() {
std::cout << func(10) << std::endl;
return 0;
}
由于此编译单元未定义 BUILD_LIBRARY
,因此 EXPORT
宏等于 __declspec(dllimport)
。