doubo1883 2018-11-02 14:41
浏览 392
已采纳

正确更改* C.char的正确方法

I am new with go and cgo and after browsing the internet for some time I have not figured out a good and fast way to change a char* from go.

What is the fastest way to change *C.char from go&

Here is my code and my attempt to change the string(It does not work)

package asciiEngine

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

type Screen struct {
    Width, Height int
    Length        C.ulong
    Data          *C.char
    GoData        string
    HConsole      C.HANDLE
    BytesWritten  C.DWORD
    Start         C.COORD
}

func (s Screen) Draw() {
    C.WriteConsoleOutputCharacter(s.HConsole, s.Data, s.Length, s.Start, &s.BytesWritten)
}

func CreateScreen(width, height int) Screen {
    screen := Screen{
        Width:        width,
        Height:       height,
        Length:       C.ulong(width * height),
        Data:         (*C.char)(C.malloc(C.ulonglong(width * height))),
        HConsole:     C.CreateConsoleScreenBuffer(C.GENERIC_READ|C.GENERIC_WRITE, 0, nil, C.CONSOLE_TEXTMODE_BUFFER, nil),
        BytesWritten: 0,
    }
    screen.GoData = C.GoString(screen.Data) // my attempt to get a reference to the C string
    //C.SetConsoleActiveScreenBuffer(screen.HConsole)
    return screen
}

main.go:

package main

// #include "stdio.h"
// void print(char* data) {
//  printf(data);
// }
import "C"

import (
    "fmt"

    "github.com/demantar/ascii-engine"
)

func main() {
    screen := asciiEngine.CreateScreen(100, 50)
    C.print((*C.char)(screen.Data))
    fmt.Println()
    screen.GoData = "askdssdfselkkskdkflsekfjdkjfksjeflsdkfjjekdjflskasdfkksdjjekdskdfjkskd"
    C.print((*C.char)(screen.Data))
}

output

P

P

I'm also pretty new to C and am doing this because I could not find a library to do this

  • 写回答

1条回答 默认 最新

  • duan1982453 2018-11-03 17:02
    关注

    For example, use gData as a Go byte slice reference to the underlying cData C char array.

    package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    /*
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int printData(unsigned char *data) {
        return printf("cData: %lu \"%s\"
    ", (long unsigned int)strlen(data), data);
    }
    */
    import "C"
    
    func main() {
        // Allocate C data buffer.
        width, height := 8, 2
        lenData := width * height
        // add string terminating null byte
        cData := (*C.uchar)(C.calloc(C.size_t(lenData+1), C.sizeof_uchar))
    
        // When no longer in use, free C allocations.
        defer C.free(unsafe.Pointer(cData))
    
        // Go slice reference to C data buffer,
        // minus string terminating null byte
        gData := (*[1 << 30]byte)(unsafe.Pointer(cData))[:lenData:lenData]
    
        // Write and read cData via gData.
        for i := range gData {
            gData[i] = '.'
        }
        copy(gData[0:], "Data")
        gData[len(gData)-1] = 'X'
        fmt.Printf("gData: %d %q
    ", len(gData), gData)
        C.printData(cData)
    }
    

    Output:

    gData: 16 "Data...........X"
    cData: 16 "Data...........X"
    

    Reference: Command cgo

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化