【问题标题】:How to use std::vector or other container in cgo of golang?如何在 golang 的 cgo 中使用 std::vector 或其他容器?
【发布时间】:2019-09-06 00:16:20
【问题描述】:

我想将大量对象malloc到内存中。(大约1亿个对象)因为golang的gc不够有效,所以我需要使用c/c++来malloc内存并使用std::vector来保存对象。 这是我的代码,我想在 cgo 中使用 std 容器:

package main

import (
    "fmt"
)

/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>


using namespace std;

void dosome(){
    vector<int> ivec;   // empty vector
    for (vector<int>::size_type ix = 0; ix != 10; ++ix)
        ivec[ix] = ix; // disaster: ivec has no elements
}

*/
// #cgo LDFLAGS: -lstdc++
import "C"

//import "fmt"
func main() {

    C.dosome()

    var input string
    fmt.Scanln(&input)
}

并在下方显示错误消息:

go run stddemo.go 
# command-line-arguments
./stddemo.go:13:10: fatal error: 'vector' file not found
#include <vector>
     ^
1 error generated.

如何设置包含路径或有其他想法?

【问题讨论】:

    标签: go cgo


    【解决方案1】:

    虽然您可以将 C++ 与 CGo 一起使用,但您不能将该代码嵌入到 .go 文件中,因为它最终是使用 C 编译器构建的。

    相反,请将您的 dosome 函数放在与 .go 文件相同的目录中的单独 .cpp 文件中,并声明您的函数使用 C 链接。例如:

    extern "C" {
        void dosome() {
            vector<int> ivec;
            ...
        }
    }
    

    如果您在 .go 文件的 CGo 注释中包含该函数的原型,以便您可以从 Go 中调用它。

    由于您现在有多个文件,因此您不能再使用go run foo.go 速记(因为它只编译一个文件)。相反,您需要使用go run packagego build package,您的代码位于$GOPATH/src/package

    【讨论】:

    【解决方案2】:

    呃,我觉得你的结论有点太快了。 GC 成本由两件事驱动:程序产生的垃圾越多,GC 必须运行的越多。第二:要扫描的指针越多,单个 GC 所需的时间就越长。

    也就是说:只要你把你的 1 亿个东西放到一个 go slice 中并保留在那里:GC 就不需要运行太多,因为没有垃圾。第二:如果你的东西不包含指针,GC时间,如果它仍然发生,就可以了。

    那么,我的问题是:你的东西有指针吗?

    【讨论】:

    【解决方案3】:

    如果你只是想调用某人的 golang 代码,这是一种快速 ram 低效的方式:

    package main
    
    import "C"
    import "fmt"
    import "unsafe"
    
    func intArrayFromC (src unsafe.Pointer, sz int) []uint64 {
        dest := make([]uint64, sz)
        copy(dest, (*(*[1000000000]uint64)(unsafe.Pointer(src)))[:sz:sz])// big number dose not affect ram.
        return dest
    }
    
    //export doPrint
    func doPrint(src unsafe.Pointer, sz int){
        var numbers []uint64 = intArrayFromC(src, sz);
    
        for i := 0; i < len(numbers); i++ {
            fmt.Printf("%d  index: %d\n", numbers[i], i)
        }
    }
    
    func main() {}
    

    和 c++ 代码:

    #include "print.h"
    #include <string.h>
    #include <vector>
    
    int main() {
        std::vector<GoUint64> numbers{99,44,11,00,2,33,44};
    
        while (1) {
            doPrint(numbers.data(), numbers.size());
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多