doufu8887 2019-08-15 19:39
浏览 82

如何从C库检索probuf

I'm trying to communicate with a C library from Go using Google Protocol Buffers, but I can't make it work. I'm facing an error trying to send the protobuf into the C library

I'll post the minimum code to reproduce the error I'm facing right now (I've removed most of the C part as it is not relevant for this error):

    /*
    #cgo CFLAGS: -I@CURRENT_SOURCE_DIR@/../../library/crnd/include - 
    I@CMAKE_CURRENT_BINARY_DIR@/../../library
    #cgo LDFLAGS: -L@CRND_LIBRARY_PATH@ -lcrnd

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

    typedef struct SerializedStruct {
        void* data;
        int64_t size;
    } Serialized;
    */
    import "C"

    func (crnd wrapper) MyFunction() {

        // Create a protobuf
        sample_request := &messages.SampleRequest { ... add members ...}
        fmt.Printf(proto.MarshalTextString(sample_request));  // print the message to check it works

        data, err := proto.Marshal(sample_request)
        if err != nil {
            log.Fatal("marshaling error: ", err)
        }

        sample_request_serialized := C.Serialized {
            data: pointer.Save(data),
            size: C.int64_t(len(data)),
        }

        // Here I would send my protobuf to the C library, but it is not
        //  working, so I'm trying to reconstruct the protobuf to check
        //  if something is broken before getting to the C side

        // Let's reconstruct the protobuf back
        data_req := (*[1 << 30]byte)(sample_request_serialized.data)[:int(sample_request_serialized.size):int(sample_request_serialized.size)]
        sample_req := &messages.SampleRequest{}
        err := proto.Unmarshal(data_req, sample_req)
        if err != nil {
            log.Fatal("unmarshaling error: ", err)
        }
    }

I get the following error:

unmarshaling error: proto: crnd.SampleRequest: illegal tag 0 (wire type 0)
  • 写回答

1条回答 默认 最新

  • doulin9679 2019-08-16 08:47
    关注

    I managed to make it work creating a copy of the buffer (taken from this question):

        ...
    
        p := C.malloc(C.size_t(len(data)))
        defer C.free(p)
        cBuf := (*[1 << 30]byte)(p)
        copy(cBuf[:], data)
    
        sample_request_serialized := &C.Serialized {
            data: p,
            size: C.int64_t(len(data)),
        }
    
    评论

报告相同问题?

悬赏问题

  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 请问这个是什么意思?
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。