【问题标题】:What is GTEST_API_ in GTEST_API_ int main(int argc, char **argv) {}?GTEST_API_ int main(int argc, char **argv) {} 中的 GTEST_API_ 是什么?
【发布时间】:2016-11-11 22:00:31
【问题描述】:

要使用 Google 测试框架,应该(?)使用 main 函数:

GTEST_API_ int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  [...]
  return RUN_ALL_TESTS();
}

GTEST_API_ 是什么?

在文件 gtest-port.h 中我可以看到如下内容:

# if GTEST_LINKED_AS_SHARED_LIBRARY
#  define GTEST_API_ __declspec(dllimport)
# elif GTEST_CREATE_SHARED_LIBRARY
#  define GTEST_API_ __declspec(dllexport)
# endif
#elif __GNUC__ >= 4 || defined(__clang__)
# define GTEST_API_ __attribute__((visibility ("default")))
#endif // _MSC_VER

#ifndef GTEST_API_
# define GTEST_API_
#endif

这里是__declspec的一些描述: https://msdn.microsoft.com/en-us/library/dabb5z75.aspx

__declspec Visual Studio 2015 其他版本 Microsoft 特定

用于指定存储类信息的扩展属性语法 使用 __declspec 关键字,它指定一个 给定类型将与 Microsoft 特定的存储类一起存储 下面列出的属性。其他存储类修饰符的示例 包括 static 和 extern 关键字。但是,这些关键字是 C 和 C++ 语言的 ANSI 规范的一部分,因此 不包含在扩展属性语法中。扩展属性 语法简化和标准化 Microsoft 特定的扩展,以 C 和 C++ 语言。

我不明白。

这里我有一个C++函数的描述:

http://www.cplusplus.com/doc/tutorial/functions/

类型名称(参数1,参数2,...){语句}

在哪里: - type 是函数返回值的类型。 [...]

GTEST_API_ 对返回的 int 有什么改变吗?

【问题讨论】:

    标签: c++ googletest


    【解决方案1】:

    完整的源代码是:

    #ifdef _MSC_VER
    # if GTEST_LINKED_AS_SHARED_LIBRARY
    #  define GTEST_API_ __declspec(dllimport)
    # elif GTEST_CREATE_SHARED_LIBRARY
    #  define GTEST_API_ __declspec(dllexport)
    # endif
    #elif __GNUC__ >= 4 || defined(__clang__)
    # define GTEST_API_ __attribute__((visibility ("default")))
    #endif // _MSC_VER
    
    #ifndef GTEST_API_
    # define GTEST_API_
    #endif
    

    在构建共享库(windows 中的dll 或Linux 中的共享对象)时,默认情况下Microsoft Visual C++ 不会导出任何内容,我们需要使用IAT 来找到合适的函数。此外,gcc(从第 4 版开始)和 clang 将:

    使用-fvisibility=hidden,您是在告诉 GCC,每个未明确标记可见性属性的声明都具有隐藏可见性。

    这是一种优化,是对编译器的提示,即动态共享对象将直接导出函数指针,而不仅仅是动态共享对象的 IAT(Import Address Table)/GOT(Global Offset Table) 中的一个条目目的。它允许它生成更好的代码,节省从 IAT/GOT 加载的函数指针和间接跳转。

    您可以自己尝试,在 Windows 中制作一个 dll,构建它,VC++ 不会为您创建 .lib 文件,依赖项遍历器会显示没有导出函数。我不确定,但我听说您可以通过模块定义 (.DEF) 文件使用它,通常将.def 文件与 COM 一起使用。

    因此,您需要为导出的函数指定 GTEST_API_ 以启用其可见性

    进一步阅读:

    【讨论】:

      猜你喜欢
      • 2020-11-03
      • 2011-07-08
      • 2014-10-09
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      • 2014-04-23
      相关资源
      最近更新 更多