My goal is to be able to call Go functions from a Cocoa project but I just started with a pure C CoreFoundation project.
Here is my simple go package:
package hello
import "C"
import (
"fmt"
)
//export SayHello
func SayHello() {
fmt.Println("Hello, World!")
}
I build this using go install which generates the lib hello.a.
I want to be able to link this library to my CoreFoundation project so I can call SayHello from my C code.
Doing this causes Xcode to show a warning stating that hello.a was ignored because it wasn't build for the X86_64 architecture.
I can tell that the issue most likely is due to the fact that the way the Go code was compiled is not compatible with the way XCode is compiling the CoreFoundation project.
Therefore my question is: Is it possible to somehow compile my Go package in a way which is linkable with my CoreFoundation project?
You can't link a Go library into a C program. The *.a archives that go outputs are not the same format as C object files so the C compiler won't know how to link them in.
The *.a files folow the format described here: http://golang.org/cmd/pack/ and here: http://plan9.bell-labs.com/magic/man2html/1/ar
CGO allows C to call go functions and vice versa but That will require the main app to be a Go binary not a C binary in order for the linking to work correctly.
Related
I am writing a generic library in GoLang and want to publish it (like a dynamic library) to be used by other apps written in any language.
If I write this lib in C/C++, I would have generated a .dll or .so file which can be imported and used in any other language. How can I do this in GoLang?
If I just generate a Go executable, can I use it instead of a dynamic library?
You can build a C-shared library in Go, this will produce a regular .dll or .so with exported functions compatible with the C calling convention, so that they can be invoked from other languages.
Compile with go build -buildmode=c-shared.
See go build command - Build modes
For example:
src/go/main.go:
package main
import "C"
import "fmt"
//export helloLib
func helloLib(x C.int) {
fmt.Printf("Hello from Go! x=%d\n", x)
}
func main() {}
src/c/main.c:
void helloLib(int);
int main() {
helloLib(12345);
}
Building and running:
$ go build -buildmode=c-shared -o libmy.so ./src/go/
$ gcc -o test src/c/main.c libmy.so
$ ./test
Hello from Go! x=12345
$
I believe it is possible using cgo:
https://pkg.go.dev/cmd/cgo
It is stated that Go functions can be exported for use by C code.
I am writing something using cgo to interact with the gstreamer-1.0 library. I have everything almost working perfectly, but for some reason an entire header file's objects are not getting imported correctly.
go version go1.15.2 linux/amd64 for whatever that is worth
package main
// #cgo pkg-config: gstreamer-1.0
// #cgo CFLAGS: -Wno-deprecated-declarations
// #include <gst/gst.h> // using this file extensively with no issues
// #include <gst/app/gstappsink.h> // objects in this file are not getting read, but the compiler is having no issue reading it
import "C"
func init () { C.gst_init(nil, nil) }
func main () {
// ...
C.gst_app_sink_pull_sample() // a non-variadic function that does take args
// but cgo doesn't even think it exists.
// ...
}
The error back from the compiler: /tmp/go-build/cgo-gcc-prolog:64: undefined reference to 'gst_app_sink_pull_sample'
I've looked at the header file and gst_app_sink_pull_sample is indeed there. I can reproduce this both trying to build locally and in the golang docker container.
If I remove the include entirely the error is different: could not determine kind of name for C.gst_app_sink_pull_sample.
So am I the problem or is gstreamer the problem?
The appsrc and appsink symbols are not part of the base gstreamer library. Instead they are found in the extra library gstreamer-app-1.0. Add this library to your cgo pkgconfig line and it should find the missing symbols.
"undefined reference to xxx" means the C compiler of cgo recognize the definitions but it can't find the implementations (covered by corresponding C libraries)
This indicates that you have your C header files imported correctly. To solve the undefined reference problem, you just have to add some thing as below if your dynamic library is called libgstreamer.so.1.0.0
# cgo LDFLAGS: -lgstreamer
I'm brand new to Go and am not experienced in compilation issues or with C++. So starting from zero, I'm trying to compile a dll in Go and call a function in VBA. I'm developing the Go in Linux, and switching computers to try it in Windows. The VBA part may not be essential. It does serve as a way for me to test the dll call.
Here's the simple Go code:
package main
import (
"C"
"fmt"
)
func main() {
var x int
x = Test()
fmt.Println(x)
}
func Test() int {
return 666
}
It works for go build, go install, and calling main from the console.
I compile with these two commands, which both run without error, in this order. Should I be running both of them? (I'm way out of my depth here.) The target system is Windows 10, 64 bit with Office 365 ProPlus (but is Excel fundamentally 32 bit?):
env GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc go build -buildmode=c-shared -o hello.dll hello.go
env GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build -buildmode=c-shared -o hello.dll hello.go
I copy the file, hello.dll, to System32 and in VBA I declare:
Public Declare Function Test Lib "C:\Windows\System32\hello.dll" () as Long
I get the error of Run-time error '53': File Not Found, which I understand may be caused by a missing dependency.
So I run Dependency Walker. This shows me a top level of HELLO.DLL and 4 levels under it of KERNEL32.DLL, MSVCRT.DLL, WINMM.DLL, WS2_32.DLL. And it gives:
Error: At least one required implicit or forwarded depende3ncy was not found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresovled import due to a missing export function in a a delay-load dependent module.
There's a huge number of yellow question marks. And dozens of Modules with Error opening file, with names like API-MS-WIN-CORE-... and EXT-MS-WIN-NTUSER-... as well as HVSIFILETRUST.DLL and IESHIMS.DLL and EMCLIENT.DLL
So I've got a few moving parts in my lap and I'm way out of my depth. I'm hoping I'm just missing a simple step (maybe put the dll in a different folder??). If this should be an ambitious or difficult task, I should probably let it go.
i want know how go compiler work!
https://github.com/golang/go
this source Contains 88% .go file.
so this should be have another compiler to execute .go file.
Example : https://github.com/golang/go/blob/964639cc338db650ccadeafb7424bc8ebb2c0f6c/src/go/ast/ast.go
Golang use what compiler for final Generate Execute file?! and where available they source?
may be Golang generate a c code and next use GCC or ...?
New Update
i not want go1.4 then in using c.
88% source of github.com/golang/go is .go file. what compile .go file at Go Source? i want see Final GO Compiler?
https://github.com/golang/go/search?l=c
i think this called cg.
mean An old version of Go compiler (version 1.4) is used to compile newer version of Go compiler.???!
go-go1.4.3/src/go/token/token.go this is go token,lexer and is write at GO
FUNC: "func",
GO: "go",
GOTO: "goto",
IF: "if",
IMPORT: "import",
so where main compiler for execute .go file?
go-go1.4.3/src/runtime/compiler.go
// Copyright 2012 The Go Authors. All rights reserved.
package runtime
// Compiler is the name of the compiler toolchain that built the
// running binary. Known toolchains are:
//
// gc The 5g/6g/8g compiler suite at code.google.com/p/go.
// gccgo The gccgo front end, part of the GCC compiler suite.
//
const Compiler = "gc"
go-go1.4.3/src/cmd/gc$ make
go tool dist install -v
make: go: Command not found
../../Make.dist:13: recipe for target 'install' failed
make: *** [install] Error 127
make gc why need Go?!
Last version of GO Language how work?! mean how this generate a output for cross platform? this use generate code to C and then use c compiler?
According to https://golang.org/doc/go1.5#implementation and https://www.infoq.com/news/2015/01/golang-15-bootstrapped , Go was originally implemented in C but became self-hosted at version 1.5. Bootstrapping is the process of compiling a compiler with itself. The Go developers wrote a C -> Go transpiler to convert the original C compiler to Go, then they hand-edited the Go code to make it idiomatic.
I am writing a Go wrapper for a C library in Go. The problem is, that the C library is not available on many Linux distributions, so I want a solution where i "go get github.com/me/mylibrary" does not require anybody to have the library installed.
One solution would be to just add the source of the library into a sub directory. Then when my project is build with go get I need to automatically build this library, too. But I have no idea how I can automate this.
Alternatively I could have a script that downloads the source, extracts and builds it
But I have no Idea how to connect these build steps with the go build tool.
linking a static library is also not the easiest.
#cgo linux LDFLAGS: ./MyLib/lib/libMyLib.a -lstdc++ -lm -lX11
works as long as i build from my library, but as soon as I want to build from another project the relative path is from that project and not from my library, so it fails.
As per http://golang.org/cmd/cgo/#hdr-Using_cgo_with_the_go_command
When the Go tool sees that one or more Go files use the special import
"C", it will look for other non-Go files in the directory and compile
them as part of the Go package. Any .c, .s, or .S files will be
compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
compiled with the C++ compiler.
So you can include the C library source in your repository and go will build it automatically. That page also explains how to pass build flags to the compilers and probably anything else you might need to know.