-1

I wanna import a c-shared-library to go that generated by Cython in python 3.7, try do it by cgo.

in this case:

go version go1.12.7 linux/amd64

Python 3.7.3

Cython version 0.29.12

os: Manjaro 18.0.4

Kernel: x86_64 Linux 5.1.19-1

I will continue: make a python file vim pylib.pyx:

#!python
cdef public void hello():
     print("hello world!")

and run python -m cython pylib.pyx for generate the c-shared-library, I have two files, pylib.c and pylib.h. now, try import these to golang, so make a go file vim test.go:

package main

/*
#include </usr/include/python3.7m/Python.h>
#include "pylib.h"
*/
import "C"
import "fmt"

func main() {
   C.hello()
   fmt.Println("done")
}

finaly, I run go run test.go: I have the following output:

# command-line-arguments
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_51159acd5c8e_Cfunc_hello':
/tmp/go-build/cgo-gcc-prolog:48: undefined reference to `hello'
collect2: error: ld returned 1 exit status

I try import it to c too but I encountered a similar output like this:

undefined reference to `hello'
ld returned 1 exit status

I don't know what to do, help me, please. :(

hamid ghadery
  • 31
  • 1
  • 5
  • The cgo docs only show this working with single line comments `//`, have you tried that? – Jessie Jul 31 '19 at 18:21
  • 1
    That question is way too broad. Let’s start with the fact that cythonized files .c/.h aren’t shared objects. Then you need too embed the python interpreter - the list goes on and on... – ead Jul 31 '19 at 18:24
  • @Jesse thanks for feedback <3. Do you mean? ... //#include //#include "pylib.h" import "C" ... so I have same problem too. – hamid ghadery Jul 31 '19 at 18:29
  • I think you should read - in detail - the section of the Cython documentation describing how to call a Cython module from C and then reproduce that in Go as closely as possible. – DavidW Jul 31 '19 at 18:47
  • @ead first I tried import go lib to python, It done with ctypes in python and I wanted to do the opposite, And I read documents from various sites that said I should do it. I got help from these: [this](https://stackoverflow.com/questions/45419532/use-generated-header-file-from-cython) and any more that I can't finde them. I thought be import to go like import to c. I had a similar output, of course. – hamid ghadery Jul 31 '19 at 18:51
  • @davidw I couldn't find anything to helpful, Can you find it to help me?or something. – hamid ghadery Jul 31 '19 at 18:57
  • 1
    [This is the relevant section](https://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html#using-cython-declarations-from-c); it follows the same pattern as ead's answer from the question you link above and for example the "main" function includes a number of things that you ignore here. – DavidW Jul 31 '19 at 19:03
  • @DavidW so thanks, I have to study it now. <3 – hamid ghadery Jul 31 '19 at 19:15
  • @hamidghadery as you work with Python3.7 please take my last edit into consideration: https://stackoverflow.com/posts/45424720/revisions – ead Jul 31 '19 at 19:31
  • @hamidghadery Btw, don't mind the downvotes - the question isn't bad - it is just too broad : it would take hours to answer it propertly. I think you will be able to handle it with links provided by DavidW - and then you can write an answer yourself. If not, you can come back with a more specific question. – ead Jul 31 '19 at 19:35
  • 1
    @ead I don't actually think it is that broad - I'd guess that someone familiar with (C)Go could translate the working C examples in the documentation really quite quickly. That person definitely isn't me. (My problem with this question is that it doesn't seem to have started from those examples so there's a lot wrong, but hopefully OP can fix that...) – DavidW Jul 31 '19 at 20:47

1 Answers1

1

I run go run test.go: I have the following output:

# command-line-arguments
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_51159acd5c8e_Cfunc_hello':
/tmp/go-build/cgo-gcc-prolog:48: undefined reference to `hello'
collect2: error: ld returned 1 exit status

We can generate an equivalent error message with the following code.

package main

/*
#include <math.h>
*/
import "C"
import "fmt"

func main() {
    cube2 := C.pow(2.0, 3.0)
    fmt.Println(cube2)
}

Output:

$ go run cube2.go
# command-line-arguments
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_f6c6fa139eda_Cfunc_pow':
/tmp/go-build/cgo-gcc-prolog:53: undefined reference to `pow'
collect2: error: ld returned 1 exit status
$ 

In both cases, ld (the linker) can't find a C function after looking in the usual places: undefined reference to 'pow' or undefined reference to 'hello'.

Let's tell cgo where to find the C pow function in the C math library: m.

For cgo, using ld flags,

#cgo LDFLAGS: -lm

GCC: 3.14 Options for Linking

-llibrary
    Search the library named library when linking.

Updating the previous code,

package main

/*
#cgo LDFLAGS: -lm
#include <math.h>
*/
import "C"
import "fmt"

func main() {
    cube2 := C.pow(2.0, 3.0)
    fmt.Println(cube2)
}

Output:

$ go run cube2.go
8
$

This illustrates a basic cgo principle: include a C header file for your C library and point to the location of the C library.


References:

Cgo and Python : Embedding CPython: a primer

peterSO
  • 158,998
  • 31
  • 281
  • 276
  • 1
    Actually, because the Python interpreter must be embeded there is a little bit more to it. We need a "translation" to go of https://stackoverflow.com/questions/45419532/use-generated-header-file-from-cython or https://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html#using-cython-declarations-from-c – ead Jul 31 '19 at 20:59