1

I am using some standard libraries to develop a general interface for some devices. In some part of code I have

//header.h

#ifndef _M_X64
#  define GC_CALLTYPE __stdcall
#else
#  define GC_CALLTYPE /* default */  //this is my case
#endif

...


typedef int32_t GC_ERROR;

...


/* typedefs for dynamic loading */

#define GC_API_P(function) typedef GC_ERROR( GC_CALLTYPE *function )
GC_API_P(PTLOpen)( TL_HANDLE *phTL );

and in my source files I have

//source1.cpp

TLOpen(&hTl)

//source2.cpp

#define FUNCTION_POINTER(function, ptype, hModule) \
   ((function) = reinterpret_cast<ptype>(GetProcAddress((hModule), #function)))  // What is this #?
GC::PTLOpen TLOpen = 0;
FUNCTION_POINTER(TLOpen, GC::PTLOpen, hModule);

I want to find out:

  1. What is the TLopen() declaration? I replaced macros and got this:

typedef int32_t( GC_CALLTYPE *PTLOpen )( TL_HANDLE *phTL );

But I have learned function pointers differently and I expected something like this:

typedef int32_t( *PTLOpen )( TL_HANDLE *phTL );

Is the above declaration still a function pointer one? What about GC_CALLTYPE?

  1. What is that # sign before function in defining FUNCTION_POINTER macro?

  2. Where is the body of TLopen() function? I have some .lib and .dll files to be included. May the body exist in those files in compiled form?

IndustProg
  • 627
  • 1
  • 13
  • 33

1 Answers1

1
  1. GC_CALLTYPE is in a place where a calling convention specifier can be (like __stdcall). Can be because don't forget that very easily GC_CALLTYPE can also expand to an empty string. A quick search gave a question where this syntax is discussed here in SO: How to declare an __stdcall function pointer

  2. This is called stringification: for example #function will expand to "xyz" if the corresponding macro argument was xyz. More here.

  3. Yes, it can, in either actually. Your API will tell you how to do the compilation so that the program can find the function. This is the whole purpose of having libraries and a linker.

Community
  • 1
  • 1
The Vee
  • 11,420
  • 5
  • 27
  • 60
  • So that is still a function pointer declaration. Please notice that in my case `_M_X64` is defined and `#define GC_CALLTYPE`, so `GC_CALLTYPE` is nothing but a macro! How does it work? – IndustProg Dec 11 '16 at 06:42
  • I am also curious to know if there is a way to detect that in which `.lib` file the body of a particular function exists. In other words, is there a way to find that, for example, `func1` is defined in `.lib3` or `func3` in `.lib2`? – IndustProg Dec 11 '16 at 06:50
  • 1
    @GmtK Sorry, I overlooked the "this is my case". It's even easier then: after the preprocessor pass the compiler will only see `typedef int32_t( *PTLOpen )( TL_HANDLE *phTL );`. The expansion `/* default */` is as good as white space, and actually gets replaced by that. – The Vee Dec 12 '16 at 12:20
  • @GmtK Unfortunately I don't know Windows tools. In Linux you have several ways of browsing through the symbols of a static or a dynamic library so there will be some as well. But that's something for another question. – The Vee Dec 12 '16 at 12:22