首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用CGO获取realpath?

如何使用CGO获取realpath?
EN

Stack Overflow用户
提问于 2020-06-25 13:26:06
回答 2查看 130关注 0票数 1

我有一小段C代码,用来获得似乎可以工作的realpath:

代码语言:javascript
复制
#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;
}

我正在尝试为它创建一个包装器(仅用于学习目的):

代码语言:javascript
复制
package main

/*
#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;
}
*/
import "C"
import (
    "fmt"
    "os"
    "path"
    "unsafe"
)

func getArgv() string {
    return fmt.Sprintf("./%s", path.Base(os.Args[0]))
}

func main() {
    slink := C.CString(getArgv())
    defer C.free(unsafe.Pointer(slink))
    ret := C.getrpath(slink)
    fmt.Println(C.GoString(ret))
}

我无法将值返回到main() Golang函数中。如果我在C getrpath()函数中放置一个print,它将打印路径。任何建议都是非常感谢的。

EN

回答 2

Stack Overflow用户

发布于 2020-06-25 14:21:34

问题是你的C函数返回在C堆栈上分配的内存,这在C中是未定义的行为(在实践中可能会导致无用的值):

代码语言:javascript
复制
char* getrpath(char *symlink) {
    char *symlinkpath = symlink;
    char actualpath [PATH_MAX];
    symlink = realpath(symlinkpath, actualpath);
    return symlink;
}

您需要返回堆分配的内存。如下所示:

代码语言:javascript
复制
char* getrpath(char *symlink) {
    char *actualpath = malloc(PATH_MAX);
    return realpath(symlink, actualpath);
}

或者更简单--因为如果您为第二个参数传入NULL,则会将getpath定义为malloc内存本身:

代码语言:javascript
复制
char *getrpath(char *symlink) {
    return realpath(symlink, 0);
}

(我还删除了您引入的变量,但这不是编辑的重要部分)。

票数 1
EN

Stack Overflow用户

发布于 2020-06-26 12:56:59

up最终得到了它,但必须直接调用C.realpath:

代码语言:javascript
复制
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())
}

另外,我不会检查它是否返回任何东西。最好检查一下是否真的在使用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62568431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档