2011-06-27 24 views
5

argument typu void (*)(int) jest niezgodna z parametrem typu __sighnd64_tSignal obsługi w języku C++

Poniżej jest mój prosty kod:

#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); 
} 

Pracuję na OpenVMS. Czy mogę uniknąć błędu kompilacji przez pewnego rodzaju rzutowanie typu? Mój kompilator oczekuje `__sighnd64_t __64_signal (int, __sighnd64_t);

Dodanie otaczającego przewodnika extern zadziałało. Dzięki

+0

To dziwne, bo AFAIK '__sighnd64_t' jest typedef'd do' void (*) (int) '. Ale są inne problemy w twoim kodzie ... na przykład 'cout' musi być niezadeklarowanym identyfikatorem, ponieważ nie używasz' std :: ' –

+0

Prawdopodobnie musisz zajrzeć do pliku dla swojego kompilatora (który?) , aby zobaczyć dokładnie to, czego oczekuje dla parametrów "signal()". –

+2

Przepraszamy za może głupie pytanie, ale czy masz problem z kompilacją? na Linuksie kompiluje się i działa, dodając odpowiednio std :: gdzie jest to potrzebne. – dave

Odpowiedz

3

obsługi sygnału nie jest C++, ale C. Ten błąd jest trochę dziwne ...

W takich przypadkach staramy się używać extern „C” wokół przewodnika (do zdefiniowania jej jako funkcji C) , jako https://stackoverflow.com/users/775806/n-m powiedział w komentarzach. Modern <signal.h> z openvms ma już zewnętrzne "C" wewnątrz: 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 tylko o C, nie C++.

Another doc mówi, że procedura obsługi sygnału (łapacz) muszą być zadeklarowane w C jako

void func(int signo); 
+3

Nie wierzę, że musisz deklarują funkcje jako "zewnętrzne" C "', aby mogły być wywołane z kodu C w ogóle. Myślę, że musisz to zrobić tylko wtedy, gdy są one przywoływane po imieniu z kodu C. Ponieważ wskaźnik do obsługi sygnału jest przekazywany, oznacza to, że nie trzeba go deklarować "extern" C "'. – Omnifarious

+0

Ale dodanie extern "c" zadziałało – Sam

+1

@Sam: To jest interesujące. Zastanawiam się, czy konwencja wywoływania funkcji jest częścią typu w twoim systemie. – Omnifarious