GTEST_API_ int main(int argc, char **argv) {} 中的 GTEST_API_ 是什么?

What is GTEST_API_ in GTEST_API_ int main(int argc, char **argv) {}?

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

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 Other Versions Microsoft Specific

The extended attribute syntax for specifying storage-class information uses the __declspec keyword, which specifies that an instance of a given type is to be stored with a Microsoft-specific storage-class attribute listed below. Examples of other storage-class modifiers include the static and extern keywords. However, these keywords are part of the ANSI specification of the C and C++ languages, and as such are not covered by extended attribute syntax. The extended attribute syntax simplifies and standardizes Microsoft-specific extensions to the C and C++ languages.

我不明白。

这里我有一个C++函数的说明:

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

type name ( parameter1, parameter2, ...) { statements }

Where: - type is the type of the value returned by the function. [...]

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

完整的源代码是:

#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 将:

With -fvisibility=hidden, you are telling GCC that every declaration not explicitly marked with a visibility attribute has a hidden visibility.

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

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

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

进一步阅读: