I am trying to import some C code for use in my Golang application. I am really new to Go so I most likely have done something stupid here:
I have one file main.go in the main directory and yolo.go in the /yolo subdirectory along with all my C code.
yolo.go
package yolo
import "C"
func Vals() string {
return "Good to go!"
}
main.go
package main
import "fmt"
import "./yolo"
func main() {
fmt.Printf(yolo.Vals())
fmt.Printf("test")
}
This seems to compile fine - but none of the code in the main() function in main.go runs - no output is given, but no errors are either. If I forget about the import "C" everything runs just fine and I get the output I expect. What am I doing wrong?
Related
I am trying to use Cgo to export a function that initializes a zap logger. The function is written in Go but I am working towards the goal of being able to call this function in a C script and actually use the function in the C script. For example, my init function looks like this:
func initLogger() *zap.Logger {
logger, _ := zap.NewProduction()
return logger
}
Now, I want to be able to use this function in a c script by exporting it using cgo. So, I would do //export initLogger and then build a .so and .h file from this go file and link it to a c script to build an executable. So basically, in my C script, I want to be able to do something like :
logger = initLogger()
logger.Info("Hello World!")
This would log:
{"level":"info","ts":1654031030.1591902,"caller":"go-kitLog/exLogger.go:14","msg":"Hello World!"}
The problem I am facing is that *zap.Logger does not export to C, it gives this error: Go type not supported in export: *zap.Logger. Have any of you possibly dealt with a similar situation? If so, how did you solve it?
I am trying to build a program in python using Cython and PyInstaller. Before starting, I built this test program. However, the two modules aren't working together at all. I have tried them both separately, and they work.
I looked at this question but that doesn't work.
I also tried using cython to compile it to c and then use gcc, but that doesn't work either (I added the python.h file, and gcc just aborts after complaining that the keyword doesn't exist)
#hello.pyx
import pygame
def say_hello_to(name):
print("Hello %s!" % name)
#hello.py
from hello import say_hello_to
say_hello_to('Me')
#setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
name='Hello world app',
ext_modules=cythonize("hello.pyx"),
zip_safe=False,
)
All of this works in CPython, with :
python3 setup.py build_ext --inplace
Then
python3 hello.py
But PyInstaller keeps complaining it can't find the module hello. I tried add-data and add-binaries, as well as editing the spec file, and it still doesn't work, saying:
invalid add_data_or_binary value: 'home:Achyut-BK:hello.cpython-38-x86_64-linux-gnu.so'
I'm quite new to python that I always use by writing script in spyder and running them in its Ipython console with python3.6.2 .
I'm trying to write a simple module from a "swig_example.c" file following a couple of swig tutorial (http://www.swig.org/tutorial.html, http://www.swig.org/Doc1.3/Python.html#Python_nn6).
My aim is to be able to run a script "main_python.py" which should look like:
import swig_test
print(swig_test.fact(4))
where fact is a function defined in the original c source.
The source file is "swig_example.c":
/* File: swig_example.c */
#include "swig_example.h"
int fact(int n) {
if (n == 0) {
return 1;
}
else {
return n * fact(n-1);
}
}
The header file is as simple as:
/* File: swig_example.h */
int fact(int n);
and the interface one:
/* File: swig_example.i */
%module swig_test
%{
#include "swig_example.h"
%}
%include "swig_example.h"
When in the terminal I run:
swig -python swig_example.i
a "swig_example_wrap.c" and a "swig_test.py" files are created.
How should I proceed to have my "main_python.py" working?
(It now returns a "No module named '_swig_test' error).
I would like to have some script (maybe using distutils?) so that each time I modify the .c source I can easily update the module without changing the "main_python.py" file.
If you have any solution which uses Xcode instead of spyder it would be well accepted.
I think that the question could be useful to many that are new to python (and Mac actually...) and try to use it while not throwing away their previous works...
EDIT:
I -partially- solved the problem. Now the main point remain Spyder.
I create the files ".c", ".h" and ".i" the way I described. Then, following this post (Python.h not found using swig and Anaconda Python) I create, in the same folder, my "setup.py" file:
from distutils.core import setup, Extension
example_module = Extension('_example', sources=['example.c','example.i'])
setup(name='example', ext_modules=[example_module], py_modules= .["example"])
Then, In anaconda navigator I open the terminal of the environment I'm working in, move to the right folder and run:
python setup.py build_ext --inplace
If now I open spyder everything works the desired way. But If I now want to modify my C source, say add a new function, problems arises. I modify the ".c", ".h" and ".i" files annd thenn re-run in the terminal the previous line. The "example.py" file result to e correctly modified (it innncludes the attribute of the new function), but when try to import the module in spyder (import example) changes are nnot registered and an error message "_example has no attribute "new function" is given in the Ipython console unless I restart Spyder itself.
Is there faster way to fix it? (maybe this is the interaction mentioned in the comments... )
Thank you all :-)
I have a main.go file that I worked on and now I'm trying to organize since it became a little lengthy. I want to create a new file, put some functions in it and then include it in main.go and use those functions. That new file will be in the same directory as main.go. Anybody have any idea how to do this?
As long as the go files are in the same package, you do not need to import anything.
Example:
project/main.go:
package main
import "fmt"
func main() {
fmt.Println(sayHello())
}
project/utils.go:
package main
func sayHello() (string) {
return "hello!"
}
To run: go run main.go utils.go or go run *.go
You don't have to do any including (importing). Just use the same package name in both files.
Old question, but no matter...
You can create go.mod file at the same directory you keep your source files with the help of following command:
go mod init main
This will create mod file for main package.
Each source file should start with package main directive.
After that you can build your project as follows:
go build .
And if you need build and run:
go run .
I am trying to write a Cython wrapper for a C Library. I have read through the docs carefully but I must be missing something since I cannot get the following simple Cython code to work.
I created a shared library from the following:
mathlib.c
#include "mathlib.h"
int add_one(int x){
return x + 1;
}
mathlib.h
extern int add_one(int x);
Then I created the library like so:
gcc -c mathlib.c
gcc -shared -o libmathlib.so mathlib.o -lm
My Cython files are mathlib.pyx, cmathlib.pyd, and setup.py
cymathlib.pyx
from mathlib cimport add_one
def add_one_c(int x):
print add_one(x)
return x
mathlib.pyd
cdef extern from "mathlib.h":
int add_one(int x)
setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
setup(
ext_modules = cythonize([Extension("cymathlib", ["cymathlib.pyx"])], libraries ["mathlib"])
)
The module cymathlib.so is created but when I attempt to import it in Python I get the following error: ImportError: dlopen(./cymathlib.so, 2): Symbol not found: _add_one Referenced from: ./cymathlib.so Expected in: flat namespace in ./cymathlib.so"
It looks like something went wrong with your Extension specification, which should be something like:
ext_modules = cythonize([Extension("cymathlib",
["cymathlib.pyx"],
libraries=["mathlib"],
library_dirs=["/place/path/to/libmathlib.so/here"]
)])
To be able to use the module, it must be able to find libmathlib.so at run time, since it will look in that file for the actual implementation of add_one. Apart from copying the file to /usr/lib or /usr/local/lib (and running ldconfig again), you can also set an environment variable to make sure the library can be found:
export LD_LIBRARY_PATH=/place/full/path/to/libmathlib.so/here
It's also possible to add the C code into the python module you're creating (so no libmathlib.so will need to be compiled or used anymore). You just need to add the mathlib.c file to the list of cython sources:
ext_modules = cythonize([Extension("cymathlib",
["cymathlib.pyx","mathlib.c"]
)])