Home > Blockchain >  Calling C function from Go with buffer as argument
Calling C function from Go with buffer as argument

Time:05-26

We have (for all intents and purposes) something similar to the following C code.

calc.h

#pragma once

extern "C" {
    void doCalc(uint8_t** buffer);
}

calc.cpp

#include <cstdint>
#include "calc.h"

void doCalc(uint8_t** buffer) {
    uint8_t lb[256];

    for (int i = 0; i < 256; i  ) {
        lb[i] = i;
    }

    *buffer = new uint8_t[256];

    std::memcpy(*buffer, lb, 256);
}

We need to call this method from Go, but unsure how to construct the buffer variable on the Go side to pass in (seeing as the length is unknown prior to calling - the 256 in the C function should be considered unknown).

CodePudding user response:

I've made a slightly different example that fits your use case:

package main

/*
#include <stdio.h>

void print_words(int count, char** words) {
    for (int i = 0; i < count; i  = 1) {
        printf(words[i]);
    }
}
*/
import "C"
import "unsafe"

func main() {
    words := make([]*C.char, 2)

    words[0] = C.CString("Hello ")
    words[1] = C.CString("World\n")

    C.print_words((C.int)(len(words)), (**C.char)(unsafe.Pointer(&words[0])))
}

CodePudding user response:

Based off @Jacob Wischnat 's answer (thanks!), I was able to get it working for my example:

func main() {
    cBuf := make([]*C.uint8_t, 1)

    C.doCalc((**C.uint8_t)(unsafe.Pointer(&cBuf[0])))
    
    gBuf := C.GoBytes(unsafe.Pointer(cBuf[0]), 256)

    // ...
}
  • Related