【问题标题】:Passing string literal to C将字符串文字传递给 C
【发布时间】:2014-03-19 03:28:35
【问题描述】:

我正在玩在 go 中调用 C 代码。但是,当我尝试从 go 中使用 printf 时,我收到有关格式字符串不是字符串文字的警告:

package main

// #include <stdio.h>
import "C"

func main() {
    C.printf(C.CString("Hello world\n"));
}

警告:

警告:格式字符串不是字符串文字(可能不安全)[-Wformat-security]

如何将字符串文字传递给像 printf 这样的 C 函数?是否有类似于C.CString() 的功能可以使用,还是不可能,我应该忽略此警告?

【问题讨论】:

  • 请尝试C.printf("%s",C.CString("Hello world\n"));
  • @AnkitB 不起作用;如果是这样,那么我可以简单地使用C.printf("Hello world\n");
  • 为什么特别是printf?有一个压倒一切的原因吗​​?所写的警告是正确的:所写的代码正在传递给 C 的 printf 一个在技术上在运行时构造的值。众所周知,printf 第一个位置的动态值可以成为攻击的向量。 C 没有任何偏见:它只知道printf 的第一个位置有一些值,它不是文字字符串标记。编译器给出了一个合法的编译时警告。

标签: c string go cgo


【解决方案1】:

使用 printf 时,格式字符串最好是字符串文字而不是变量。并且 C.CString 是 go runtime 转换的字符指针。而且您可能不会在最新版本中使用 printf 的可变参数。在其他情况下,如果要删除警告,请使用类型转换:

package main

/*
typedef const char* const_char_ptr;
#include <stdio.h>
*/
import "C"

func main() {
    C.puts((C.const_char_ptr)(C.CString("foo")))
}

编辑

注意,C.CString 的调用是免费的。

package main

/*
typedef const char* const_char_ptr;
#include <stdio.h>
*/
import "C"
import "unsafe"

func main() {
    ptr := (C.const_char_ptr)(C.CString("foo"))
    defer C.free(unsafe.Pointer(ptr))
    C.puts(ptr)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-26
    相关资源
    最近更新 更多