Golang中如何从C++传递Map(无序映射)并进行初始化后返回

Golang中如何从C++传递Map(无序映射)并进行初始化后返回 我正在尝试将一个无序映射从 C++ 传递到 Go 语言,反之亦然。我已经将 Go 代码编译为动态链接库(使用 Windows 系统)并生成了头文件和库文件。我在 C++ 中包含该头文件并链接该库。当我调用该方法时,出现了错误。

Go 代码如下:

func Initialize(m *map[*C.char]*C.char) {
ctr1 := C.CString("MyName")
ctr2 := C.CString("1")
(*m)[ctr1] = ctr2
}

C++ 代码如下:

std::unordered_map<char*, char*> *mapInstance;
Initialize((void **)&mapInstance);

包含的头文件中有:

typedef void *GoMap;
extern void Initialize(GoMap* p0);

出现的错误是:

panic: assignment to entry in nil map

goroutine 17 [running, locked to thread]: main.Initialize(0x9d560ff860) D:/GoLang/Learning/Map/Return_Map/MapReturn.go:10 +0x95 main._cgoexpwrap_671a9fb041ec_Initialize(0x9d560ff860) _cgo_gotypes.go:61 +0x32

请指导我正确的方向。


更多关于Golang中如何从C++传递Map(无序映射)并进行初始化后返回的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何从C++传递Map(无序映射)并进行初始化后返回的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题在于你传递了一个未初始化的 Go map 指针给 Go 函数。在 Go 中,map 必须使用 make() 或字面量初始化后才能使用,否则是 nil map。

以下是修正后的代码:

Go 代码:

package main

/*
#include <stdlib.h>
*/
import "C"
import "unsafe"

//export Initialize
func Initialize(m *map[*C.char]*C.char) {
    if *m == nil {
        *m = make(map[*C.char]*C.char)
    }
    
    ctr1 := C.CString("MyName")
    ctr2 := C.CString("1")
    defer C.free(unsafe.Pointer(ctr1))
    defer C.free(unsafe.Pointer(ctr2))
    
    (*m)[ctr1] = ctr2
}

func main() {}

C++ 代码:

#include <iostream>
#include <unordered_map>
#include "your_header.h"

int main() {
    // 声明一个指向 map 的指针
    std::unordered_map<char*, char*>* mapInstance = nullptr;
    
    // 调用 Go 函数,传递指针的地址
    Initialize(&mapInstance);
    
    // 使用 map
    if (mapInstance) {
        for (const auto& pair : *mapInstance) {
            std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
        }
    }
    
    return 0;
}

关键修改:

  1. 在 Go 函数中检查 map 是否为 nil,如果是则使用 make() 初始化
  2. 添加了内存管理,使用 defer C.free() 释放 CString
  3. 在 C++ 中正确传递指针的地址

编译命令示例:

# 编译 Go 为动态库
go build -buildmode=c-shared -o libmap.dll map.go

# C++ 编译时需要链接该库
g++ -o main main.cpp -L. -lmap

这样修改后应该能解决 nil map 的 panic 问题。

回到顶部