2015-03-06 26 views
5

volte, un puntatore NULL può essere necessaria un'API C.CGO, come passare parametro NULL alla funzione C

è che possibile in CGO?

Per esempio, voglio passare un argomento null per strcmp() in un programma in linguaggio Go:

package strutil 

/* 
#include <stdlib.h> 
#include <string.h> 
*/ 
import (
    "C" 
    "unsafe" 
) 

func StrCmp(a, b string) int { 
    pca := C.CString(a) 
    defer C.free(pca) 
    pcb := C.CString(b) 
    defer C.free(pcb) 
    ret := C.strcmp(pca, pcb) 
    return int(ret) 
} 

Se ho impostato pca-nil, questo errore si verifica:

Exception 0xc0000005 0x0 0x0 0x76828b21 
PC=0x76828b21 
signal arrived during cgo execution 

strutil._Cfunc_strcmp(0x0, 0x761b00, 0x0) 
    strutil/_obj/_cgo_gotypes.go:79 +0x49 
strutil.StrCmp(0x19, 0x10, 0x4bbf38, 0xa, 0x1fbc1f98, 0x0, 0x0, 0xffff, 0x0,  0x0, ...) 

Quindi, come posso passare NULL a strcmp?

Grazie

+0

non ho usato l'API C in Go, ma per consentire la funzione di accettare una ' null', si poteva fare 'func StrCmp (a, b stringa *) int {...}' –

risposta

7

Se si vuole passare NULL a una funzione C si può semplicemente passare nil in esso.

Tuttavia non è documentato cosa succede quando si invia un puntatore NULL alla funzione strcmp(...). Direi che lo strcmp fallisce quando passi NULL ad esso. Sarebbe meglio controllare il tuo input in anticipo e restituire un errore quando uno dei tuoi ingressi è impostato su zero.

package main 

/* 
#include <stdlib.h> 
#include <string.h> 
*/ 
import "C" 

import (
    "errors" 
    "fmt" 
    "unsafe" 
) 

func StrCmp(a, b *string) (int, error) { 
    if nil == a || nil == b { 
     return 0, errors.New("Both strings have to be set") 
    } 
    pca := C.CString(*a) 
    defer C.free(unsafe.Pointer(pca)) 
    pcb := C.CString(*b) 
    defer C.free(unsafe.Pointer(pcb)) 

    ret := C.strcmp(pca, pcb) 
    return int(ret), nil 
} 

func main() { 
    left := "Left" 
    right := "Right" 
    fmt.Println(StrCmp(&left, &right)) 
    fmt.Println(StrCmp(&left, &left)) 
    fmt.Println(StrCmp(nil, &right)) 
    fmt.Println(StrCmp(&left, nil)) 
} 

Se necessario un esempio come passare NULL per una funzione che non accetta puntatori NULL:

package main 

/* 
#include <stdio.h> 
int am_i_null(int* pointer) { 
    if (NULL == pointer) { 
    return -1; 
    } 
    return *pointer; 
} 
*/ 
import "C" 

import (
    "fmt" 
    "unsafe" 
) 

func main() { 
    fmt.Println(C.am_i_null(nil)) 

    var cInteger C.int = 8 
    fmt.Println(C.am_i_null(&cInteger)) 

    var goInteger int = 7 
    fmt.Println(C.am_i_null((*C.int)(unsafe.Pointer(&goInteger)))) 
} 
+2

7.1.4.1 della norma C specifica che passa NULL per 'risultati strcmp' a comportamento non definito (dal' isn strcmp'' t documentato per accettare puntatori NULL). –

+0

Grazie, @Sander, proverò i tuoi exmaples – tanbro

Problemi correlati