英文:
CGO, how to pass NULL parameter to C function
问题
有时候,在C API中可能需要使用NULL指针。
在CGO中是否可能实现这一点?
例如,我想在Go语言程序中将一个空参数传递给strcmp()
函数:
package strutil
/*
#include <stdlib.h>
#include <string.h>
*/
import "C"
import "unsafe"
func StrCmp(a, b string) int {
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)
}
如果我将pca
设置为nil
,会出现以下错误:
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, ...)
那么,我该如何将NULL传递给strcmp函数呢?
谢谢。
英文:
Sometimes, a NULL pointer may be needed for a C API.
is that possible in CGO?
For example, I want to pass a null argument to strcmp()
in a Go language program:
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)
}
If I set pca
to nil
, this error occurs:
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, ...)
So, how can I pass NULL to strcmp?
Thanks
答案1
得分: 14
如果你想将NULL传递给C函数,你可以简单地将nil
传递给它。
然而,当你将一个NULL指针传递给函数strcmp(...)
时,文档中没有说明会发生什么。我猜想,当你将NULL传递给它时,strcmp会失败。最好在之前检查输入,并在其中一个输入设置为nil时返回错误。
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))
}
如果有必要,下面是一个接受NULL指针的函数如何传递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))))
}
英文:
If you want to pass NULL to a C function you could simply pass nil
into it.
However it's not documented what happens when you send a NULL pointer to the function strcmp(...)
. I'd guess that the strcmp fails when you are passing NULL to it. It would be better to check your input on before hand and return an error when one of your inputs is set to nil.
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))
}
If necessary an example how to pass NULL to a function that does accept NULL pointers:
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))))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论