更新:
我正在研究通过GCO实现C库的Golang代码。在C函数的参数之间有一个* Cchar对象。
我使用C.CString()函数将字符串转换为* char,但是当我需要使用for循环实现它时遇到了问题。
感谢@peterSON,我可以继续前进。现在,程序将运行更长的时间,直到失败。现在我得到结果,直到第三个周期(五个周期)为止。当开始第四个时,它再次指示“退出状态3221226356”
这是一段代码:
package main
//#include <stdio.h>
//#include <stdlib.h>
//#cgo CFLAGS: -I C:/Go-Project/src/Astrocal
//#cgo LDFLAGS: -L C:/Go-Project/src/Astrocal72 -lswedll64
//#include "swephexp.h"
import "C"
import (
"fmt"
"unsafe"
)
...
func (P DATA) FixStarUT() {
C.swe_set_ephe_path(C.CString("C:/sweph/ephe")) // connect to library C.
var Cxx [6]C.double
var serr string
var Cserr *C.char = C.CString(serr)
var FixStarCchar *C.char = C.CString("")
var iFLAG = []uint32{33026, 35074, 266, 2314, 98562, 100610, 65802, 67851} // 33026, 35074, 266, 2314, 98562, 100610, 65802, 67851
var fixStarSlice = []string{"aboras", "achernar", "adara", "ain", "vega"}
fmt.Println("Memory Address of FixStarCchar before For Range ->", FixStarCchar)
// For Range 1
for i, valFixStar := range fixStarSlice {
defer C.free(unsafe.Pointer(FixStarCchar))
defer C.free(unsafe.Pointer(Cserr))
FixStarCchar = C.CString(valFixStar)
fmt.Println("\nExternal cycle:", i, "Star (valFixStar):", valFixStar)
fmt.Println("Memory Add. of FixStarCchar ->", FixStarCchar)
// For Range 2
for i2, valSistem := range iFLAG {
// C functions
C.swe_set_topo(C.double(P.LONsite), C.double(P.LATsite), C.double(P.ALTsite))
C.swe_fixstar_ut(FixStarCchar, C.double(P.JulianDay), C.int(valSistem), &Cxx[0], Cserr)
// Exporting results to a slice
var positionFixStar []float64
positionFixStar = append(positionFixStar, float64(Cxx[0]), float64(Cxx[1]), float64(Cxx[2]), float64(Cxx[3]), float64(Cxx[4]), float64(Cxx[5]))
fmt.Println("\tInternal cycle:", i2, "\tSistem:", valSistem, "\tPosition:", positionFixStar)
}
}
C.swe_close() // disconnect library C
}
输出:
PS C:\Go-Project\src\Astrocal72> go run main.go
Memory Address of FixStarCchar before For Range -> 0x1019c80
External cycle: 0 Star (valFixStar): aboras
Memory Add. of FixStarCchar -> 0x1019ca0
Internal cycle: 0 Sistem: 33026 Position: [331.7560238873596 -23.63731225621964 1 0 0 0]
Internal cycle: 1 Sistem: 35074 Position: [343.5555314743071 -32.70632643606941 1 0 0 0]
Internal cycle: 2 Sistem: 266 Position: [331.7521303243937 -23.639006118391627 1 0 0 0]
Internal cycle: 3 Sistem: 2314 Position: [343.5525162650043 -32.709352136426915 1 0 0 0]
Internal cycle: 4 Sistem: 98562 Position: [307.45659891000344 -23.63731225621964 1 0 0 0]
Internal cycle: 5 Sistem: 100610 Position: [319.25465207507114 -32.705260202398776 1 0 0 0]
Internal cycle: 6 Sistem: 65802 Position: [307.4527053470375 -23.63900611839163 1 0 0 0]
Internal cycle: 7 Sistem: 67851 Position: [319.2516367429912 -32.7082857906988 0.9999999999999999 0 0 0]
External cycle: 1 Star (valFixStar): achernar
Memory Add. of FixStarCchar -> 0x101b3a0
Internal cycle: 0 Sistem: 33026 Position: [344.86781077811537 -59.37245156484419 1 0 0 0]
Internal cycle: 1 Sistem: 35074 Position: [24.13636287205359 -57.39092532881141 0.9999999999999999 0 0 0]
Internal cycle: 2 Sistem: 266 Position: [344.86287075464315 -59.37668655703472 1 0 0 0]
Internal cycle: 3 Sistem: 2314 Position: [24.138688732702057 -57.39568950801329 1 0 0 0]
Internal cycle: 4 Sistem: 98562 Position: [320.56838580075924 -59.37245156484419 0.9999999999999998 0 0 0]
Internal cycle: 5 Sistem: 100610 Position: [359.83323867384445 -57.39150066286222 1 0 0 0]
Internal cycle: 6 Sistem: 65802 Position: [320.563445777287 -59.37668655703472 0.9999999999999999 0 0 0]
Internal cycle: 7 Sistem: 67851 Position: [359.835563909282 -57.39626493585631 1 0 0 0]
External cycle: 2 Star (valFixStar): adara
Memory Add. of FixStarCchar -> 0x101ae40
Internal cycle: 0 Sistem: 33026 Position: [110.31533627711894 -51.36455324165249 1 0 0 0]
Internal cycle: 1 Sistem: 35074 Position: [104.3395190395512 -28.925572447433648 1 0 0 0]
Internal cycle: 2 Sistem: 266 Position: [110.32409258962711 -51.363920733883326 0.9999999999999999 0 0 0]
Internal cycle: 3 Sistem: 2314 Position: [104.34580120684954 -28.92581091916995 0.9999999999999999 0 0 0]
Internal cycle: 4 Sistem: 98562 Position: [86.01591129976276 -51.36455324165249 0.9999999999999998 0 0 0]
Internal cycle: 5 Sistem: 100610 Position: [80.0401030111902 -28.927947460228687 0.9999999999999999 0 0 0]
Internal cycle: 6 Sistem: 65802 Position: [86.02466761227095 -51.363920733883326 1 0 0 0]
Internal cycle: 7 Sistem: 67851 Position: [80.04638532334661 -28.92818591289178 1 0 0 0]
External cycle: 3 Star (valFixStar): ain
Memory Add. of FixStarCchar -> 0x101ad70
exit status 3221226356
无论如何,希望您能帮助我解决这个问题。
最佳答案
C.Free
与C.free
不同。
例如,从文档中:
package main
// #include <stdio.h>
// #include <stdlib.h>
//
// static void myprint(char* s) {
// printf("%s\n", s);
// }
import "C"
import "unsafe"
func main() {
cs := C.CString("Hello from stdio")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
输出:
Hello from stdio
Command cgo
exit status 3221226356
消息可能表示内存损坏。除其他外,您对C.swe_fixstar_ut
的调用看起来可疑。如果您在Go函数中隐藏cgo C API实现,则它会更健壮和更易读。例如,一些未编写的,未经测试的代码:
package main
/*
#cgo CFLAGS: -I C:/Users/peter/astro
#cgo LDFLAGS: -L C:/Users/peter/astro -lswedll64
#include "swephexp.h"
*/
import "C"
import (
"errors"
"strconv"
)
type SweErr struct {
Code int32
Err error
}
func (e SweErr) Error() string {
return strconv.Itoa(int(e.Code)) + ": " + e.Err.Error()
}
func SweFixstarUt(star string, tjd float64, iflag int32) (name string, xx []float64, rc int32, err error) {
// Programming interface to the Swiss Ephemeris
// https://www.astro.com/swisseph/swephprg.htm
// 3.5. Error handling and return values
// 5. Fixed stars functions
// 5.2. swe_fixstar2_ut(), swe_fixstar2(), swe_fixstar_ut(), swe_fixstar()
var swe struct {
rc C.int32
star [C.AS_MAXCH + 1]C.char
tjd_ut C.double
iflag C.int32
xx [6]C.double
serr [C.AS_MAXCH + 1]C.char
}
if len(star) > len(swe.star)-1 {
star = star[:len(swe.star)-1]
}
for i := 0; i < len(star); i++ {
swe.star[i] = C.char(star[i])
}
swe.star[len(star)] = 0
swe.tjd_ut = C.double(tjd)
swe.iflag = C.int32(iflag)
swe.rc = C.swe_fixstar_ut(
&swe.star[0], swe.tjd_ut, swe.iflag, &swe.xx[0], &swe.serr[0],
)
swe.star[len(swe.star)-1] = 0
swe.serr[len(swe.serr)-1] = 0
if swe.rc < 0 {
err := SweErr{
Code: int32(swe.rc),
Err: errors.New(C.GoString(&swe.serr[0])),
}
return "", nil, 0, err
}
name = C.GoString(&swe.star[0])
xx = make([]float64, len(swe.xx))
for i := range xx {
xx[i] = float64(swe.xx[i])
}
rc = int32(swe.rc)
return name, xx, rc, nil
}
func main() {}
引用:
Programming interface to the Swiss Ephemeris
The C Programming Language, 2nd Edition
The Go Programming Language
关于c - Golang的字符串和C Char *之间的转换为For Range时出现内存问题,退出状态3221226356,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62352410/