习明昊
习明昊

Reputation: 711

How to use std::vector or other container in cgo of golang?

I want to malloc large number of objects in to memory.(about 100 million objects) because the gc of golang is not effective enough,so i need to use c/c++ to malloc memory and use std::vector to hold objects. this is my code,i want use std container in cgo:

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

and have error message below:

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

how can i set the include path or is there another idea?

Upvotes: 6

Views: 4852

Answers (3)

user_number153
user_number153

Reputation: 562

if you just want to call someone's golang code this is a quick ram inefficient way:

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() {}

and the c++ code:

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

Upvotes: 1

James Henstridge
James Henstridge

Reputation: 43939

While you can use C++ with CGo, you can't embed that code inside the .go file, since it ultimately gets built with a C compiler.

Instead, place your dosome function in a separate .cpp file in the same directory as the .go file, and declare your function to use C linkage. For example:

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

If you include a prototype for the function in the CGo comment in the .go file so you can call it from Go.

Since you have multiple files now, you can't use the go run foo.go shorthand any more (since it only compiles a single file). Instead, you will need to use go run package or go build package, where your code is located at $GOPATH/src/package.

Upvotes: 6

nes1983
nes1983

Reputation: 15756

Uhh I think your conclusions are a bit too fast. GC cost is driven by two things: The more garbage your program produces, the more the GC will have to run. Second: The more pointers there are to scan, the longer a single GC will take.

That is to say: as long as you put your 100 million things into a go slice and keep them there: the GC won't have to run much, because there's no garbage. And second: if your things don't contain pointers, GC time, should it still occur, will be fine.

So, my question is: do your things have pointers?

Upvotes: 4

Related Questions