繁体   English   中英

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_

什么 RTC_EXPORT class RTC_EXPORT PeerConnectionInterface :public rtc::RefCountInterface {...}; 做?

通常我们将 C++ 中的class Myclass{...}定义为class Myclass{...} 额外的 MACRO 通常有什么作用?

除了 Dmitry 的回答之外,我还想添加一些实用工具来检查__declspec()的影响。 考虑以下源文件:

// library.cpp
__declspec(dllexport) int func(int x) { return 2 * x; }

从开始菜单中的 Visual Studio 安装启动本机工具命令提示符。 在那里,您可以使用以下命令编译library.cpp并将其链接到 DLL:

> cd <Directory containing library.cpp>
> cl /c library.cpp
> link library.obj /DLL /NOENTRY

library.dll旁边应该有一个新创建的library.cpp 以下命令检查导出的符号:

> 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)注释的类才会导出其所有成员函数。

摘要:为了从 DLL 导出函数,您必须使用__declspec(dllexport)对其进行注释。

现在,从 DLL 导出类的常用方法是在头文件中定义这样一个#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)

宏在您的代码段中定义:

#ifdef WEBRTC_LIBRARY_IMPL
#define RTC_EXPORT __declspec(dllexport)  
#else
#define RTC_EXPORT __declspec(dllimport)
#endif

这允许对动态库和调用者代码使用相同的类声明。

dllexport 和 dllimport 存储类属性是 Microsoft 特定的 C 和 C++ 语言扩展。 您可以使用它们从 DLL 导出和导入函数、数据和对象。

https://docs.microsoft.com/en-us/cpp/cpp/dllexport-dllimport?view=vs-2019

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM