drjk87189 2019-09-11 20:08
浏览 103

未找到符号:将`go`库链接到带有`cgo`和`pybind11`的`python`中

I'm trying to make a go function available in Python. I'm using the standard cgo approach combined with pybind11 but not able to get it working. I'm leveraging this demo which works on its own but not when trying to link the go code. Equally I'm able to call the go code from C but not from Python.

UPDATE

I've confirmed that the issue is definitely in the linking step by using a shared library not compiled from Go. The error is very likely in either the shared library definition or the CMake file setup.

I've got the following file in go:

package main

import "C"

//export Sum
func Sum(a, b int) int {
    return a + b
}


func main() {}

That I'm compiling into a C shared library hello.so via:

go build -buildmode=c-shared -o hello.so hello.go

Then adding a C++ file example.cpp:

#include <pybind11/pybind11.h>
#include "hello.h"


int add(int i, int j) {
    long long other_sum = Sum(2, 3);
    return i + j;
}

namespace py = pybind11;

PYBIND11_MODULE(example, m) {
    // optional module docstring
    m.doc() = "pybind11 example plugin";

    // define add function
    m.def("add", &add, "A function which adds two numbers");
}

Then, with the full source code of pybind11 into a folder called pybind11, I run the following:

mkdir build && cd build && cmake .. && make

which successfully creates a Python library in folder build.

However, when calling the Python CLI cd build && python3 and then importing add with from example import add, I run into the following issue:

ImportError: Symbol not found: _Sum

This seems like a library linking issue, but it doesn't go away with the following CMakeLists.txt configuration:

cmake_minimum_required(VERSION 2.8.12)
project(example)

find_package(PythonLibs)
include_directories(${PYTHON_INCLUDE_DIRS})

add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

# first attempt to link
include_directories(.)
link_directories($PWD)

# second attempt to link
add_library(hello SHARED IMPORTED)
set_property(TARGET hello PROPERTY IMPORTED_LOCATION "./hello.so")

Any thoughts on why the attempt to link is failing?

UPDATE

Code for hello.h:

/* Code generated by cmd/cgo; DO NOT EDIT. */

/* package command-line-arguments */


#line 1 "cgo-builtin-export-prolog"

#include <stddef.h> /* for ptrdiff_t below */

#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H

#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif

#endif

/* Start of preamble from import "C" comments.  */




/* End of preamble from import "C" comments.  */


/* Start of boilerplate cgo prologue.  */
#line 1 "cgo-gcc-export-header-prolog"

#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H

typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;

/*
  static assertion to make sure the file is being used on architecture
  at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

#endif

/* End of boilerplate cgo prologue.  */

#ifdef __cplusplus
extern "C" {
#endif


extern GoInt Sum(GoInt p0, GoInt p1);

#ifdef __cplusplus
}
#endif
  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 Matlab问题解答有两个问题
    • ¥50 Oracle Kubernetes服务器集群主节点无法访问,工作节点可以访问
    • ¥15 LCD12864中文显示
    • ¥15 在使用CH341SER.EXE时不小心把所有驱动文件删除了怎么解决
    • ¥15 gsoap生成onvif框架
    • ¥15 有关sql server business intellige安装,包括SSDT、SSMS。
    • ¥15 stm32的can接口不能收发数据
    • ¥15 目标检测算法移植到arm开发板
    • ¥15 利用JD51设计温度报警系统
    • ¥15 快手联盟怎么快速的跑出建立模型