【问题标题】:Does this still declare an alias for a type of pointer function?这是否仍然为一种指针函数声明别名?
【发布时间】:2016-12-10 15:36:36
【问题描述】:

我正在使用一些标准库为某些设备开发通用接口。 在代码的某些部分我有

//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 );

在我的源文件中

//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);

我想知道:

  1. TLopen() 声明是什么?我替换了宏并得到了这个:

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

但我对函数指针的学习方式不同,我希望是这样的:

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

上面的声明还是一个函数指针吗? GC_CALLTYPE呢?

  1. 定义FUNCTION_POINTER宏时function前面的#符号是什么?

  2. TLopen() 函数的主体在哪里?我要包含一些 .lib.dll 文件。正文可以以编译形式存在于这些文件中吗?

【问题讨论】:

    标签: c++ function-pointers declaration calling-convention


    【解决方案1】:
    1. GC_CALLTYPE 位于calling convention 说明符可以存在的位置(如__stdcall)。 可以 因为不要忘记GC_CALLTYPE 也可以很容易地扩展为空字符串。快速搜索给出了一个问题,这里在 SO 中讨论了这种语法:How to declare an __stdcall function pointer

    2. 这称为字符串化:例如,如果对应的宏参数为 xyz#function 将扩展为 "xyz"。更多here

    3. 是的,实际上两者都可以。您的 API 将告诉您如何进行编译,以便程序可以找到该函数。这就是拥有库和linker 的全部目的。

    【讨论】:

    • 所以这仍然是一个函数指针声明。请注意,在我的例子中,_M_X64 是定义的,#define GC_CALLTYPE,所以GC_CALLTYPE 只不过是一个宏!它是如何工作的?
    • 我也很想知道是否有一种方法可以检测到 .lib 文件中存在特定函数的主体。换句话说,有没有办法找到,例如func1.lib3func3中定义在.lib2
    • @GmtK 抱歉,我忽略了“这是我的情况”。那就更简单了:在预处理器通过后,编译器只会看到typedef int32_t( *PTLOpen )( TL_HANDLE *phTL );。扩展 /* default */ 与空白一样好,实际上被它所取代。
    • @GmtK 不幸的是我不知道 Windows 工具。在 Linux 中,您可以通过多种方式浏览静态或动态库的符号,因此也会有一些方式。但这是另一个问题。
    猜你喜欢
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多