【问题标题】:Signal handling in C++C++ 中的信号处理
【发布时间】:2011-09-23 09:47:06
【问题描述】:

void (*)(int) 类型的参数与__sighnd64_t 类型的参数不兼容

下面是我的简单代码:

#include <iostream>
#include <string>
#include <signal.h>
#include <ctype>
#include <stdlib.h>
#include <stdio.h>
typedef struct mystrcut
{

  int a;
  char *b;

} mystr;

void set_string ( char **, const char * );
void my_handler(int s)
{
    printf("Caught signal %d\n",s);
    exit(1);

}

int main()
{
    const std::string str1[] = {"hello1", "hello2"};
    char str2[50];
    size_t size1 = str1[1].size();
    cout << size1;
    memcpy (str2, str1[1].c_str(), size1);

    cout << str2;
    mystr *m = NULL;
    m = new mystrcut;
    m->a = 5;

    set_string(&m->b, "hello");

    cout << m->b;
    delete []m->b;
//    void (*prev_fn)(int);
    signal (SIGINT,my_handler);
    return 0;
}
void set_string ( char **a, const char *b)
{
    *a = new char [strlen(b)+1];
    strcpy (*a, b);
}

我正在开发 openvms。我可以通过某种类型转换来避免编译错误吗?我的编译器需要 `__sighnd64_t __64_signal(int, __sighnd64_t);

在处理程序 extern c 周围添加有效。谢谢

【问题讨论】:

  • 这很奇怪,因为 AFAIK __sighnd64_t 的类型定义为 void (*)(int)。但是您的代码中还有其他问题...例如 cout 必须是未声明的标识符,因为您不使用 std::
  • 您可能必须查看编译器的 文件(哪个?),以准确了解它对 signal() 参数的期望。
  • 抱歉这个可能很愚蠢的问题,但是你有编译问题吗?在 linux 上它可以编译和工作,在需要的地方正确添加 std::。
  • 我也看不出拨打signal有任何问题。但是他传给signal的函数有一个很严重的问题;你不能打电话给printf。 (另外,如果您只关心 Unix 机器的可移植性,您应该使用 sigaction 而不是 signal。)
  • 尝试将您的处理程序声明为extern "C"。这是严格意义上的标准要求。 gcc 不强制执行此操作,但其他一些编译器会执行此操作。

标签: c++ signal-handling openvms


【解决方案1】:

信号处理不是C++,而是C。这个错误有点奇怪……

在这种情况下,请尝试在处理程序周围使用 extern "C"(将其定义为 C 函数),正如 https://stackoverflow.com/users/775806/n-m 在 cmets 中所说的那样。来自 openvms 的现代 &lt;signal.h&gt; 内部已经有 extern "C":http://wasd.vsm.com.au/conan/sys$common/syslib/decc$rtldef.tlb?key=SIGNAL&title=Library%20/sys$common/syslib/decc$rtldef.tlb&referer=http%3A/wasd.vsm.com.au/conan/sys$common/syshlp/helplib.hlb

HP docs says 仅关于 C,而不是 C++。

Another doc 表示信号处理程序(捕获器)必须在 C 中声明为

 void func(int signo);

【讨论】:

  • 我认为您根本不需要将函数声明为 extern "C" 以便从 C 代码中调用它们。我认为只有在 C 代码中按名称引用它们时才需要这样做。由于传递了指向信号处理程序的指针,这意味着它不需要声明extern "C"
  • @Sam:这很有趣。我想知道要使用的函数调用约定是否是您系统上类型的一部分。
  • @Omnifarious:这在标准语言中称为“语言链接”,它类型的一部分(具有不同语言链接的两个函数类型是不同的类型即使它们在其他方面相同——C++03 7.5 IIRC)。一些编译器使 C 和 C++ 函数类型兼容,无论好坏。
  • @n.m.:有趣。这是我从现在开始必须牢记的事情。我不知道有人这样做。谢谢。
猜你喜欢
  • 2011-01-29
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多