【问题标题】:Golang CGO with large char pointer - SEGSERV带有大字符指针的 Golang CGO - SEGSERV
【发布时间】:2017-08-25 22:39:13
【问题描述】:

我从 TagLib 库中读取了大量数据并传递给 GoLang(mpeg 图像数据)。

这里是获取数据的地方:

void audiotags_mpeg_artwork(TagLib::MPEG::File *mpegFile, int id) {
    TagLib::ID3v2::Tag *id3v2 = mpegFile->ID3v2Tag(false);
    if (id3v2!=nullptr) {
        const TagLib::ID3v2::FrameList frameList = id3v2->frameListMap()["APIC"];
        for(auto it = frameList.begin(); it != frameList.end(); it++) {
            TagLib::ID3v2::AttachedPictureFrame * frame = (TagLib::ID3v2::AttachedPictureFrame *)(*it);
            if (frame!=nullptr && frame->size() > 0) {
                const auto &apicBase64 = frame->picture().toBase64();
                auto len = apicBase64.size();
                if (len > 0) {
                    // Generate memory for key
                    char* key = new char[5];
                    memcpy(key, "APIC", 4);
                    key[4]='\0';

                    // Generate memory for picture data
                    char* val = new char[len];
                    memcpy (val, apicBase64.data(), len);

                    // Send to GoLang
                    go_map_audiotags(id, key, val);

                    // Free memory
                    delete[] key;
                    delete[] val;
                }
            }
        }
    }
}

此时,go_map_autotags 起作用了(我对其他数据使用了类似的方法)。这也适用于其他图片数据,但取决于大小这将崩溃:

意外故障地址0x766a000

致命错误:故障

[信号SIGSEGV:分段违规代码=0x1 addr=0x766a000 pc=0x404530b]

在 GoLang 中,我有以下导出:

//export go_map_audiotags
func go_map_audiotags(id C.int, key *C.char, val *C.char) {
    m := maps[int(id)]
    k := strings.ToLower(C.GoString(key))
    log.Println("go_map_audiotags k:", k) // <--- works
    v := C.GoString(val) // <--- crashes
    log.Println("go_map_audiotags v:", v) // <--- Does not reach
    m[k] = v
}

有没有更好的方法来传输这些数据?我假设正在发生的事情是: 1) 即将达到 C.char 限制 2)由于某种原因,C++ 在 GoLang 中设置 v 之前会回收内存

【问题讨论】:

  • apicBase64.data() nul 终止了吗?
  • @tkausl 最好的识别方法是什么?根据 TagLib 文档:frame->picture():taglib.org/api/…ByteVector.data():taglib.org/api/…
  • Nul-自己终止它,看看它是否仍然崩溃。
  • 如果它不是以null结尾的,你怎么知道字符串的长度?
  • 谢谢大家,这是导致问题的原因。我很惊讶只有 1/76000 个文件有这个问题,我认为由于它的大小是另一个原因。

标签: c++ c go segmentation-fault taglib


【解决方案1】:

val 中存储的数据不是以空值结尾的。在您的 C 代码中,当您使用 memcpy 进行复制时,不包括空终止符。在C代码中,将代码改为:

// Generate memory for picture data
char* val = new char[len+1];
memcpy (val, apicBase64.data(), len);
val[len] = '\0';

【讨论】:

    猜你喜欢
    • 2016-06-25
    • 2016-07-12
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 2019-06-03
    • 2017-02-13
    • 1970-01-01
    相关资源
    最近更新 更多