C++ 什么是GTEST_API_uuuu在GTEST_API_uuuint main(intargc,char**argv){}中的GTEST_API_uuu?

C++ 什么是GTEST_API_uuuu在GTEST_API_uuuint main(intargc,char**argv){}中的GTEST_API_uuu?,c++,googletest,C++,Googletest,要使用Google测试框架,应(?)使用主功能: GTEST_API_ int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); [...] return RUN_ALL_TESTS(); } 什么是GTEST\u API 在文件gtest port.h中,我可以看到如下内容: # if GTEST_LINKED_AS_SHARED_LIBRARY # define GTEST_API_

要使用Google测试框架,应(?)使用主功能:

GTEST_API_ int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  [...]
  return RUN_ALL_TESTS();
}
什么是
GTEST\u 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
下面是对
\u declspec
的一些描述:

__declspec Visual Studio 2015其他特定于Microsoft的版本

用于指定存储类信息的扩展属性语法 使用_declspec关键字,该关键字指定 给定类型将与Microsoft特定的存储类一起存储 属性列在下面。其他存储类修饰符的示例 包括静态和外部关键字。但是,这些关键字是 C语言和C++语言的ANSI规范的一部分,以及 扩展属性语法不包括这些属性。扩展属性 语法简化并标准化了特定于Microsoft的对 C语言和C++语言。 我不明白

<>这里我有C++函数的描述:

类型名称(参数1,参数2,…{statements}

其中: -type是函数返回的值的类型。[……]


那么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中构建共享LabAll(Windows中的DLL或Linux中的共享对象)时,默认情况下,微软Visual C++将不导出任何东西,我们需要使用IAT来找到适当的功能。此外,gcc(第4版)和clang将:

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

这是一种优化,提示编译器动态共享对象将直接导出函数指针,而不仅仅是动态共享对象的IAT(导入地址表)/GOT(全局偏移量表)中的一个条目。它可以生成更好的代码,节省IAT/GOT的函数指针负载和间接跳转

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

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

进一步阅读:


    • 完整的源代码是:

      #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中构建共享LabAll(Windows中的DLL或Linux中的共享对象)时,默认情况下,微软Visual C++将不导出任何东西,我们需要使用IAT来找到适当的功能。此外,gcc(第4版)和clang将:

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

      这是一种优化,提示编译器动态共享对象将直接导出函数指针,而不仅仅是动态共享对象的IAT(导入地址表)/GOT(全局偏移量表)中的一个条目。它可以生成更好的代码,节省IAT/GOT的函数指针负载和间接跳转

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

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

      进一步阅读: