如何使用CGO获取realpath?
我有一点C代码,可以让realpath看起来正常工作:如何使用CGO获取realpath?,c,go,cgo,C,Go,Cgo,我有一点C代码,可以让realpath看起来正常工作: #include <limits.h> #include <stdio.h> #include <stdlib.h> char* getrpath(char *symlink) { char *symlinkpath = symlink; char actualpath [PATH_MAX]; symlink = realpath(symlinkpath, actualpath)
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
char* getrpath(char *symlink) {
char *symlinkpath = symlink;
char actualpath [PATH_MAX];
symlink = realpath(symlinkpath, actualpath);
return symlink;
}
int main(int argc, char *argv[]) {
char *symlinkpath = argv[0];
symlinkpath = getrpath(symlinkpath);
printf("%s\n", symlinkpath);
return 0;
}
#包括
#包括
#包括
char*getrpath(char*symlink){
char*symlinkpath=symlink;
字符实际路径[PATH_MAX];
symlink=realpath(symlinkpath,actualpath);
返回符号链接;
}
int main(int argc,char*argv[]){
char*symlinkpath=argv[0];
symlinkpath=getrpath(symlinkpath);
printf(“%s\n”,符号链接路径);
返回0;
}
我正在尝试为它创建一个包装器(仅用于学习目的):
主程序包
/*
#包括
#包括
#包括
char*getrpath(char*symlink){
char*symlinkpath=symlink;
字符实际路径[PATH_MAX];
symlink=realpath(symlinkpath,actualpath);
返回符号链接;
}
*/
输入“C”
进口(
“fmt”
“操作系统”
“路径”
“不安全”
)
func getArgv()字符串{
返回fmt.Sprintf(“./%s”,path.Base(os.Args[0]))
}
func main(){
slink:=C.CString(getArgv())
延迟C.free(不安全指针(slink))
ret:=C.getrpath(slink)
fmt.Println(C.GoString(翻新))
}
我无法将值返回到main()Golang函数中。如果我在C getrpath()函数中放置一个打印,它将打印路径。非常感谢任何提示。问题在于,您的C函数返回在C堆栈上分配的内存,这在C中是未定义的行为(在实践中可能会导致垃圾值): 您需要返回堆分配的内存。像这样:
char* getrpath(char *symlink) {
char *actualpath = malloc(PATH_MAX);
return realpath(symlink, actualpath);
}
或者更简单地说——因为如果为第二个参数传递NULL,则getpath
被定义为malloc
内存本身:
char *getrpath(char *symlink) {
return realpath(symlink, 0);
}
(我还删除了您引入的变量,但这不是编辑的重要部分)。OK最终得到了它,但不得不直接调用C.realpath:
package main
/*
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
*/
import "C"
import (
"fmt"
"unsafe"
)
func currentDir() []byte {
return []byte{0x2e, 0x2f}
}
func rpath() string {
relativePath := currentDir()
limit := make([]byte, C.PATH_MAX)
slink := make([]byte, len(relativePath)+1)
copy(slink, relativePath)
C.realpath(
(*C.char)(unsafe.Pointer(&slink[0])),
(*C.char)(unsafe.Pointer(&limit[0])))
return C.GoString((*C.char)(unsafe.Pointer(&limit[0])))
}
func main() {
fmt.Println(rpath())
}
主程序包
/*
#包括
#包括
#包括
*/
输入“C”
进口(
“fmt”
“不安全”
)
func currentDir()[]字节{
返回[]字节{0x2e,0x2f}
}
func rpath()字符串{
relativePath:=currentDir()
限制:=生成([]字节,C.PATH_MAX)
slink:=生成([]字节,len(相对路径)+1)
副本(链接、相对路径)
C.realpath(
(*C.char)(不安全的.Pointer(&slink[0]),
(*C.char)(不安全的.Pointer(&limit[0]))
返回C.GoString((*C.char)(不安全的.Pointer(&limit[0]))
}
func main(){
fmt.Println(rpath())
}
我也不检查它是否返回任何东西。。。最好检查一下是否真的使用了它。太棒了。很好的解释不幸的是,我仍然无法从main()Golang函数打印
char *getrpath(char *symlink) {
return realpath(symlink, 0);
}
package main
/*
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
*/
import "C"
import (
"fmt"
"unsafe"
)
func currentDir() []byte {
return []byte{0x2e, 0x2f}
}
func rpath() string {
relativePath := currentDir()
limit := make([]byte, C.PATH_MAX)
slink := make([]byte, len(relativePath)+1)
copy(slink, relativePath)
C.realpath(
(*C.char)(unsafe.Pointer(&slink[0])),
(*C.char)(unsafe.Pointer(&limit[0])))
return C.GoString((*C.char)(unsafe.Pointer(&limit[0])))
}
func main() {
fmt.Println(rpath())
}