登录
首页 >  Golang >  Go问答

同时使用 strfmon 和 cgo

来源:stackoverflow

时间:2024-02-29 08:00:30 386浏览 收藏

学习知识要善于思考,思考,再思考!今天golang学习网小编就给大家带来《同时使用 strfmon 和 cgo》,以下内容主要包含等知识点,如果你正在学习或准备学习Golang,就都不要错过本文啦~让我们一起来看看吧,能帮助到你就更好了!

问题内容

我正在尝试通过 cgo 使用 c 函数 strfmon

有效的示例 c 代码是:

#include 
#include 

int main(void)
{
    char str[100];
    double money = 1234.56;
    strfmon(str, 100, "%i", money);
    printf("%s\n", string);
}

到目前为止我编写的 go 代码是:

package main

// #cgo CFLAGS: -g -Wall
// #include 
// #include 
import "C"
import (
    "fmt"
)

func main() {
    str := [100]C.char{}
    var money C.double = 1234.56
    C.strfmon(str, 100, "%i", money)
    fmt.Printf("%+v\n", str)
}

当我 go 运行 main.go 时,出现以下错误:

./main.go:14:2:意外类型:...

我相信 ... 指的是 strfmon 中的可变参数,但我不确定如何从 go 中解决这个问题。


解决方案


根据cgo command documentation

不支持调用可变参数 c 函数。可以通过使用 c 函数包装器来规避此问题。

并且 strfmon(3p) 确实是一个可变参数函数,如签名中的 ... 字符所示:

ssize_t strfmon(char *restrict s, size_t maxsize,
   const char *restrict format, ...);

因此,您可以在 c 中创建一个包装函数,该函数具有固定数量的参数并根据需要调用 strfmon(...),例如:

package main

// #cgo CFLAGS: -g -Wall
//
// #include 
// #include 
// #include 
//
// size_t format_amount(char * s, size_t maxsize, char * format, double amount)
// {
//   setlocale(LC_ALL, "en_US");
//   return strfmon(s, maxsize, format, amount);
// }
//
import "C"
import "fmt"
import "unsafe"

const SIZE = 100

func main() {
  str := C.CString(string(make([]byte, SIZE)))
  money := C.double(1234.56)
  format := C.CString("[%n]")

  C.format_amount(str, SIZE-1, format, money) // Call our wrapper here.
  fmt.Printf("OK: %s\n", C.GoString(str))
  // OK: [$1,234.56]

  C.free(unsafe.Pointer(str))
  C.free(unsafe.Pointer(format))
}

到这里,我们也就讲完了《同时使用 strfmon 和 cgo》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>