将strfmon与cgo一起使用

将strfmon与cgo一起使用,go,cgo,Go,Cgo,我试图使用cgo使用C函数strfmon 工作的示例C代码是: #include <stdio.h> #include <monetary.h> int main(void) { char str[100]; double money = 1234.56; strfmon(str, 100, "%i", money); printf("%s\n", string); } #包括 #包括 内部主(空) { char-str[100]; 双

我试图使用cgo使用C函数
strfmon

工作的示例C代码是:

#include <stdio.h>
#include <monetary.h>

int main(void)
{
    char str[100];
    double money = 1234.56;
    strfmon(str, 100, "%i", money);
    printf("%s\n", string);
}
#包括
#包括
内部主(空)
{
char-str[100];
双倍货币=1234.56;
strfmon(str,100,“%i”,货币);
printf(“%s\n”,字符串);
}
到目前为止,我编写的Go代码是:

package main

// #cgo CFLAGS: -g -Wall
// #include <stdlib.h>
// #include <monetary.h>
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)
}
主程序包
//#cgo CFLAGS:-g-墙
//#包括
//#包括
输入“C”
进口(
“fmt”
)
func main(){
str:=[100]C.char{}
var货币C.double=1234.56
C.strfmon(str,100,“%i”,货币)
fmt.Printf(“%+v\n”,str)
}
当我运行main.go时,我得到以下错误:

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

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

根据:

不支持调用可变C函数。通过使用C函数包装器可以避免这种情况

实际上是一个可变函数,如签名中的
字符所示:

ssize_t strfmon(char *restrict s, size_t maxsize,
   const char *restrict format, ...);
因此,您可以在C中创建一个包装函数,该函数具有固定数量的参数,并根据需要调用strfmon(…),例如:

package main

// #cgo CFLAGS: -g -Wall
//
// #include <locale.h>
// #include <monetary.h>
// #include <stdlib.h>
//
// 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))
}
主程序包
//#cgo CFLAGS:-g-墙
//
//#包括
//#包括
//#包括
//
//大小\格式\金额(字符*s,大小\最大大小,字符*格式,双倍金额)
// {
//setlocale(LC_ALL,“en_US”);
//返回strfmon(s、maxsize、format、amount);
// }
//
输入“C”
输入“fmt”
进口“不安全”
常数大小=100
func main(){
str:=C.CString(字符串(make([]字节,大小)))
货币:=C.double(1234.56)
格式:=C.CString([%n]”)
C.format\u amount(str,SIZE-1,format,money)//在这里调用我们的包装器。
fmt.Printf(“确定:%s\n”,C.GoString(str))
//OK:[1234.56美元]
C.free(不安全的指针(str))
C.free(不安全的指针(格式))
}

错误信息已不再存在。
指的是C函数中的可变参数。看看
man strfmon
为什么不使用x/text/currency或其他第三方库呢?因为我找不到一个能正确格式化某个区域设置的金额的软件包。e、 在法国,欧元符号在金额之后,在德国,它是金额的前缀