简体   繁体   English

传递给C库的函数指针的C链接

[英]C linkage for function pointer passed to C library

My case is pretty simple: I want my C++ program to deal with Unix signals. 我的情况非常简单:我希望我的C ++程序能够处理Unix信号。 To do so, glibc provides a function in signal.h called sigaction , which expects to receive a function pointer as its second argument. 为此,glibc在signal.h中提供了一个名为sigaction的函数,它希望接收一个函数指针作为它的第二个参数。

extern "C"
{
void uponSignal(int);
}

void uponSignal(int)
{
    // set some flag to quit the program
}

static
void installSignalHandler()
{
    // initialize the signal handler
    static struct sigaction sighandler;
    memset( &sighandler, 0, sizeof(struct sigaction) );
    sighandler.sa_handler = uponSignal;

    // install it
    sigaction( SIGINT, &sighandler, nullptr );
}

My question is: is the extern "C" linkage specifier necessary? 我的问题是: extern "C"链接说明符是否必要?

Bonus question: can uponSignal be declared static ? 奖金问题:onSignal可以声明为static吗?

My question is: is the extern "C" linkage specifier necessary? 我的问题是: extern "C"链接说明符是否必要?

For maximum portability, yes; 为了最大程度的便携性,是的; the C++ standard only guarantees interoperability with C via functions declared extern "C" . C ++标准仅通过声明为extern "C"函数保证与C的互操作性。

Practically, no; 实际上,没有; most sensible ABIs (including the GNU ABI used by glibc) will use the same calling convention for C and C++ non-member (and static member) functions, so that extern "C" is only needed to share the function name between languages. 最明智的ABI(包括glibc使用的GNU ABI)将对C和C ++非成员(和静态成员)函数使用相同的调用约定,因此仅需要extern "C"来共享语言之间的函数名称。

Bonus question: can uponSignal be declared static? 奖金问题: uponSignal可以声明为静态吗?

Yes. 是。 External linkage is only needed to access the function by name from other translation units; 只有从其他翻译单位按名称访问该功能才需要外部链接; it's not necessary to call the function via a function pointer. 没有必要通过函数指针调用函数。

extern C is only necessary if you export your symbols from your binary or import them from another binary (typically in both cases, a shared library), in order to avoid name mangling. 只有从二进制文件中导出符号或从另一个二进制文件(通常在两种情况下,共享库)中导入符号时,才需要使用extern C ,以避免名称损坏。

Here this is not the case, you're not linking uponSignal across various binaries so you don't need extern C . 这不是这种情况,你没有在各种二进制文件上链接到uponSignal ,所以你不需要extern C All you're doing is pass your function's address to sigaction from a function that already knows uponSignal 's address since they are (apparently) part of the same translation unit, or at the very least of the same binary. 您所做的就是将函数的地址传递给已经知道uponSignal地址的函数的sigaction ,因为它们(显然)是同一个翻译单元的一部分,或者至少是同一个二进制文件的一部分。

Bonus question: can uponSignal be declared static ? 奖金问题: uponSignal可以声明为static吗?

Sure if you want. 当然,如果你想。 uponSignal doesn't need external linkage anyway. uponSignal无论如何都不需要外部链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM