通过从C调用的go函数的参数返回值。

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

Returning values through the arguments of go function, which is called from C

问题

假设我们有一个Go函数,它对传递给它的参数进行一些操作,例如,它可以填充在C部分中分配的缓冲区并更改它,还可以处理一个整数参数,该参数是读取数据的大小。它对整数指针工作正常,但对于uint8_t类型的指针却不起作用。请看下面的代码:

package main

/*

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>

extern int some(uint8_t *, int *);

static int somewrap() {
    uint8_t *i = malloc(16);
    int A = 1;
    int *x = &A;

    some(i, x);

    fprintf(stderr, "c.wrapper, i=%s, %p, x=%d, %p\n", i, i, *x, x);

    return 0;
}

*/
import "C"

import "fmt"
import (
	"unsafe"
)

//export some
func some(i *C.uint8_t, x *C.int) C.int {
	fmt.Println("i:", i, &i, *i, "x:", x, &x, *x)

	p := []byte("xxx")
	i = (*C.uint8_t)(unsafe.Pointer(&p[0]))

	*x = C.int(42)

	fmt.Println("i:", i, &i, *i, "x:", x, &x, *x)
	return C.int(0)
}

func main() {
	C.somewrap()
}

结果如下:

i: 0x4303a40    0xc210000018 0   x: 0x7fff5fbff874 0xc210000020 1
i: 0xc210000038 0xc210000018 120 x: 0x7fff5fbff874 0xc210000020 42
c.wrapper, i=, 0x4303a40, x=42, 0x7fff5fbff874

如你所见,它对整数指针工作正常,但对于uint8_t类型的指针却不起作用。

<details>
<summary>英文:</summary>

Suppose, we&#39;ve got a Go function, which is doing something with agruments, passed to them, e.g. it could fill the buffer, allocated in the C part and changing it and for example an integer argument, which is a size of read data. It works well with an integer one, but not with a &quot;data part&quot;. Just see a code.

    package main

    /*

    #include &lt;stdio.h&gt;
    #include &lt;stdlib.h&gt;
    #include &lt;stdint.h&gt;
    #include &lt;inttypes.h&gt;

    extern int some(uint8_t *, int *);

    static int somewrap() {
        uint8_t *i = malloc(16);
        int A = 1;
        int *x = &amp;A;

        some(i, x);

        fprintf(stderr, &quot;c.wrapper, i=%s, %p, x=%d, %p\n&quot;, i, i, *x, x);

        return 0;
    }

    */
    import &quot;C&quot;

    import &quot;fmt&quot;
    import (
    	&quot;unsafe&quot;
    )

    //export some
    func some(i *C.uint8_t, x *C.int) C.int {
    	fmt.Println(&quot;i:&quot;, i, &amp;i, *i, &quot;x:&quot;, x, &amp;x, *x)

    	p := []byte(&quot;xxx&quot;)
    	i = (*C.uint8_t)(unsafe.Pointer(&amp;p[0]))

    	*x = C.int(42)

    	fmt.Println(&quot;i:&quot;, i, &amp;i, *i, &quot;x:&quot;, x, &amp;x, *x)
    	return C.int(0)
    }

    func main() {
    	C.somewrap()
    }

As a result, we&#39;ve got following:

    i: 0x4303a40    0xc210000018 0   x: 0x7fff5fbff874 0xc210000020 1
    i: 0xc210000038 0xc210000018 120 x: 0x7fff5fbff874 0xc210000020 42
    c.wrapper, i=, 0x4303a40, x=42, 0x7fff5fbff874

As you can see, it works well for integer pointer, but not for uint8_t. 

</details>


# 答案1
**得分**: 3

你正在将`i`在`some`中重新分配给另一个地址,而不是更改给定地址上的值(除非我误解了你想要实现的目标)。

    *i = *(*C.uint8_t)(unsafe.Pointer(&p[0]))

<details>
<summary>英文:</summary>

You&#39;re re-assigning `i` within `some` to another address, not change the value at the given address (unless I&#39;m misunderstanding what you&#39;re trying to accomplish)

    *i = *(*C.uint8_t)(unsafe.Pointer(&amp;p[0]))


</details>



huangapple
  • 本文由 发表于 2014年5月14日 23:07:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/23658547.html
匿名

发表评论

匿名网友

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

确定