Golang DLL and xojo

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 :slightly_frowning_face:

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