To use Google Test framework one should (?) use a main function:
GTEST_API_ int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
[...]
return RUN_ALL_TESTS();
}
What is GTEST_API_
?
In file gtest-port.h I can see something like this:
# 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
Here's some description of __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.
Which I don't understand.
Here I have a description of C++ functions:
http://www.cplusplus.com/doc/tutorial/functions/
type name ( parameter1, parameter2, ...) { statements }
Where: - type is the type of the value returned by the function. [...]
So does GTEST_API_ changes something about the returned int?
The full source code is:
#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
When you build shared libary (dll in windows or shared object in Linux), by default, Microsoft Visual C++ will not export anything, we need to use IAT to find the proper function. In addition, gcc (from version 4) and clang will:
With
-fvisibility=hidden
, you are telling GCC that every declaration not explicitly marked with a visibility attribute has a hidden visibility.
It is an optimization, a hint to the compiler that the dynamic shared object is going to export the function pointer directly rather than just an entry in the IAT(Import Address Table)/GOT(Global Offset Table) of the dynamic shared object. It allows it to generate better code, saving a function pointer load from the IAT/GOT and an indirect jump.
You can try it your self, make a dll in Windows, build it, VC++ won't create the .lib
file for you, dependency walker will show that there're no exported function. I'm not sure but I heard that you can use it via a module-definition (.DEF
) file, it is common to use .def
file with COM.
Hence, you need to specify GTEST_API_
to an exported function to enable its visibility
Further reading: