You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swig结构体识别异常:Go与C++交互时类型不匹配报错

Go与C++通过SWIG交互时结构体类型不匹配错误

错误信息

./runme.go:22:32: cannot use (*Edge)(dataPtr) (value of type *Edge) as example.Edge value in argument to example.Process: *Edge does not implement example.Edge (missing method GetW)

项目结构

./go.mod

module simple

go 1.20

./runme.go

package main

import (
        "unsafe"
        "simple/example"
)

type Edge struct {
        X, Y int64
        W    float64
}

func main() {
        data := []Edge {
                {1,2,1.0},
                {1,3,4.0},
                {2,3,3.0},
                {2,4,0.5},
        }

        dataPtr := unsafe.Pointer(&data[0])
        example.Process((*Edge)(dataPtr),int64(len(data)), int64(4))
}

./example/package.go

package example

import "C"

./example/example.i

%module example

// Typemaps for Edge struct
%typemap(in) Edge {
    $1 = *($1_ltype*)($input);
}
%typemap(in) Edge* {
    $1 = *($1_ltype*)($input);
}

%typemap(out) Edge {
    $result = new $1_btype($1);
}

%{
#include "example.h"
%}

%include "example.h"

./example/example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

typedef struct Edge
{
        long int X, Y;
        double W;
} Edge;

void Process(Edge *G, long int M, long int N);

#endif

./example/example.cpp

#include "example.h"
#include <iostream>

void Process(Edge *G, long int M, long int N) {
        // Do some work with the Edge list
        std::cout << "|V| = " << N << "  --  |E| = " << M << std::endl;

        for(int i = 0; i < M; i++) {
                std::cout << "(" << G[i].X << ", " << G[i].Y << ") = " << G[i].W << std::endl;
        }
}

问题根源

  1. SWIG会为C++的Edge结构体自动生成Go接口,包含GetW、SetW等访问方法,自定义的Edge结构体未实现这些方法,因此无法被当作example.Edge类型传入Process函数。
  2. 原SWIG的Edge* typemap配置错误:$1 = *($1_ltype*)($input);会对传入的指针进行解引用,导致试图把指针指向的结构体赋值给指针变量,类型完全不匹配。

修复方案

步骤1:修正SWIG的typemap配置

修改./example/example.i,删除错误的Edge值类型typemap,正确配置Edge*的指针传递:

%module example

// 正确处理Edge指针:直接将传入的Go指针转换为C++指针
%typemap(in) Edge* {
    $1 = ($1_ltype)$input;
}

%{
#include "example.h"
%}

%include "example.h"

步骤2:使用SWIG生成的Edge类型

不要自定义Go版Edge,直接使用SWIG生成的example.Edge,保证类型兼容:
修改./runme.go为:

package main

import (
        "unsafe"
        "simple/example"
)

func main() {
        // 使用SWIG生成的example.Edge构建数据
        data := []example.Edge{
                {X: 1, Y: 2, W: 1.0},
                {X: 1, Y: 3, W: 4.0},
                {X: 2, Y: 3, W: 3.0},
                {X: 2, Y: 4, W: 0.5},
        }

        // 获取切片首元素的指针,直接转换为example.Edge*
        dataPtr := unsafe.Pointer(&data[0])
        example.Process((*example.Edge)(dataPtr), int64(len(data)), int64(4))
}

步骤3:重新生成SWIG绑定

重新运行SWIG命令生成Go绑定代码,例如:

swig -go -cgo -intgosize 64 example/example.i

修改后,Go代码使用的是SWIG生成的与C++结构体兼容的类型,指针传递符合要求,即可正常调用Process函数。

内容的提问来源于stack exchange,提问作者Daniel Benedí

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 00:47:50