I’m traying to do a DLL to Work in VB6.
I have this code in the DLL:
package main
// +build windows win32
import (
"C"
"fmt"
)
//export GetIntFromDLL
func GetIntFromDLL() int32 {
return 42
}
//export PrintHello
func PrintHello(Name *C.char, Output **C.char) int32 {
*Output = C.CString(fmt.Sprintf("From DLL: Hello, %s!", C.GoString(Name)))
return int32(len(C.GoString(*Output)))
}
//export PrintBye
func PrintBye(Output **C.char) int32 {
*Output = C.CString(fmt.Sprintf("From DLL: Bye!"))
return int32(len(C.GoString(*Output)))
}
//export LenString
func LenString(Input *C.char) int32 {
return int32(len(C.GoString(Input)))
}
//export OutString
func OutString() (Output *C.char) {
buf := C.CString("I am out string from DLL")
return buf
}
func main() {
// main
}
set CC=mingw32-gcc
set GOOS=windows
set GOARCH=386
set CGO_ENABLED=1
go build -buildmode=c-archive main.go
mingw32-gcc -shared -o testDLL.dll testDLL.c main.a -Wl,–add-stdcall-alias -lWinMM -lntdll -lWS2_32
And the file DLL compiles well.
And I made a test app to use the dll in GO:
package main
import (
"C"
"fmt"
"syscall"
"time"
"unsafe"
)
var (
dllTest = syscall.NewLazyDLL("testDLL.dll")
procGetIntFromDLL = dllTest.NewProc("GetIntFromDLL")
procPrintHello = dllTest.NewProc("PrintHello")
procPrintBye = dllTest.NewProc("PrintBye")
procLenString = dllTest.NewProc("LenString")
procOutString = dllTest.NewProc("OutString")
)
func main() {
fmt.Println("usageDLL v1.1")
start := time.Now()
x1, _, _ := procGetIntFromDLL.Call()
fmt.Println("GetIntFromDLL():", x1)
buffer2 := make([]byte, 256)
x2, _, _ := procPrintHello.Call(uintptr(unsafe.Pointer(syscall.StringBytePtr("Juan"))), uintptr(unsafe.Pointer(&buffer2)))
fmt.Println("PrintHello('Juan',&buffer):", string(buffer2[0:x2]))
buffer3 := make([]byte, 256)
x3, _, _ := procPrintBye.Call(uintptr(unsafe.Pointer(&buffer3)))
fmt.Println("PrintBye(&buffer):", string(buffer3[0:x3]))
x4, _, _ := procLenString.Call(uintptr(unsafe.Pointer(syscall.StringBytePtr("12345678"))))
fmt.Println("LenString('12345678'):", x4)
x5, _, _ := procOutString.Call()
fmt.Println("OutString():", C.GoString((*C.char)(unsafe.Pointer(x5))))
elapsed := time.Since(start)
fmt.Printf("Generated in %s\n", elapsed)
}
All right in GO!
But I cant to work this in VB6, I have declare it so:
Declare Function GetIntFromDLL Lib "testDLL.dll" () As Long
Declare Function PrintHello Lib "testDLL.dll" (ByVal Nombre As String, ByRef Output As String) As Long
Declare Function PrintBye Lib "testDLL.dll" (ByRef Output As String) As Long
Declare Function LenString Lib "testDLL.dll" (ByVal Nombre As String) As Long
Declare Function OutString Lib "testDLL.dll" () As String
Only GetIntFromDLL() and OutString() works in VB6. The others return "Bad DLL calling convention ".
I have heard about STDCALL but i don’t know how do this.
Thanks!