Does anyone have a working example of using a DLL compiled from golang in Xojo? , the example on the xojo forums does not work with strings (I’m sure it did in an earlier version of Xojo) tried my paid Xojo support and was asked to post on forums to see if I can find a solution.l from someone else.
@einhugur found a definition for a Go string thats
type _string struct {
elements *byte // underlying bytes
len int // number of bytes
}
so instead of trying to return a Cstring try getting a ptr and then you might be able to get the Cstring out of that at offset 0
Possibly something like (haven’t tested this so …)
Declare function HelloWorld Lib "C:\Users\Dave Duke\Documents\go\listfiles\XojoUtils\mydll.dll" () as Ptr
print "After declare"
dim retPtr as Ptr
dim retval as cString
retPtrl = HelloWorld()
retVal = Ptr.CString(0)
system.DebugLog retval
MessageBox retval
Ah Bjorn thinks maybe because the string in Go ISNT necessarily null terminated this wont quite work
Would need either your code OR a compiled Intel DLL I could poke at
I’m sure we can sort this now that we know what go returns
One more tidbit
I’ve been told that it might be preferable to use cgo to make dlls
Apparently because of how Xojo plugins work
ok for all those interested watchers
in go
package main
import "fmt"
import "C"
func main() {}
//export HelloWorld
func HelloWorld() string {
return "This is output of the function in the golang created dll"
}
in xojo make a new structure
structure GoString
data as ptr
length as int64
unused as int64
end structure
tbh not sure WHY the extra unused at the end but without it things crash
then in xojo
Soft Declare Function HelloWorld Lib "mydll.dll" () as GoString
var p as GoString = HelloWorld()
MessageBox p.length.ToString()
var mb as MemoryBlock = p.data
MessageBox mb.StringValue(0, p.length)
For interested observers what DOESNT seem to work is passing such a structure BACK to Go
more digging
@bkeeney any insights from your team about why your team uses CGo for this ?
I’m assuming its a data type and calling convention issue ?
// Build shared library with:
// go build -o cgotest.dylib -buildmode=c-shared main.go
package main
import "C"
//export HelloWorld
func HelloWorld() *C.char {
return C.CString("Hello World!")
}
func main() {
// Need a main function to make CGO compile package as C shared library
}
then you can just handle the return as a cstring from the declare.
I can get more info if you need.
How do you pass data to golang from Xojo.
Dave
I’d imagine you use C data types as well
@bkeeney ?
//export HelloIntro
func HelloIntro(name *C.char) *C.char {
who := C.GoString(name)
return C.CString("Hello " + who)
}
You can do something like that… take in the C string and convert it to a go string with C.GoString()
Thanks I figured there would be a way to convert back and forth !
If I try to compile the above I get this error ( MX Linux ):
go: no Go source files
I believe this is because it appears to the compiler “C” is not used.
But of course if I comment out
import "C"
I then get the error:
./main.go:5:23: undefined: C
So there must be another little trick required here?
Show me the entire program
package main
import "C"
func HelloIntro(name *C.char) *C.char {
who := C.GoString(name)
return C.CString("Hello " + who)
}
func main() {
// Need a main function to make CGO compile package as C shared library
}
Add
Add
//export HelloIntro
Above the function HelloIntro , sounds odd but it seems to be the way to expose the function.
Still the same outcome
Looks like the compiler is making a go/no go decision
It must be something about my environment I think. Even if I take snippets from Go’s documentation if they contain
import "C"
I get that go: no Go error