从Go调用C++函数并将缓冲区作为参数传递

huangapple go评论79阅读模式
英文:

Calling C++ function from Go with buffer as argument

问题

我们有一个类似于以下C++代码的东西。

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);
}

我们需要从Go中调用这个方法,但不确定如何在Go端构造buffer变量以传入(因为在调用之前长度是未知的-应该将C++函数中的256视为未知)。

英文:

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

calc.h

#pragma once

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

calc.cpp

#include &lt;cstdint&gt;
#include &quot;calc.h&quot;

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

    for (int i = 0; i &lt; 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).

答案1

得分: 1

我已经为您制作了一个稍微不同的示例,以适应您的用例:

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])))
}

这是一个使用Go语言调用C函数的示例。在这个示例中,我们定义了一个C函数print_words,它接受一个整数和一个字符串数组作为参数,并打印出数组中的每个字符串。然后,我们在Go代码中创建了一个字符串指针数组words,并将其传递给C函数进行打印。

请注意,为了在Go和C之间传递字符串指针,我们使用了C.CString函数将Go字符串转换为C字符串,并使用unsafe.Pointer将Go指针转换为C指针。

英文:

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

package main

/*
#include &lt;stdio.h&gt;

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

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

	words[0] = C.CString(&quot;Hello &quot;)
	words[1] = C.CString(&quot;World\n&quot;)

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

答案2

得分: 0

根据 @Jacob Wischnat 的答案(谢谢!),我成功地将它应用到我的示例中:

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)

    // ...
}
英文:

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(&amp;cBuf[0])))
	
    gBuf := C.GoBytes(unsafe.Pointer(cBuf[0]), 256)

    // ...
}

huangapple
  • 本文由 发表于 2022年5月25日 20:07:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/72377358.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定