I have created a basic class that adds two numbers in c#. I have built it into a dll but when attempting to call it in golang I am unsuccessful.
Is this possible currently in golang? If so can someone provide a example how to do this?
Edit: I have included the last attempt I made at doing this. The C# dll is simply a method that adds the two numbers that are passed in.
package main
import (
"fmt"
"syscall"
)
func main() {
var mod = syscall.NewLazyDLL("MathForGo.dll")
var proc = mod.NewProc("Add");
proc.Call(2,3);
fmt.Printf("%v",proc)
}
There is a project on Github that aims to do this.
https://github.com/matiasinsaurralde/go-dotnet
C# assemblies are not the same as C or C++ and will not load using syscall like we might want.
Edit: this answer should be deleted but SO won't let me do it. It does not actually work with C#.
Yes it is possible: https://github.com/golang/go/wiki/WindowsDLLs
(Copying here in case the link dies)
There are a few ways to call "C" code from inside Go
First way: Dynamically load a dll, then call a method on it. You can call the method via "syscallXX" (the XX is number of parameters, but if it has few than that, like if you need seven parameter, then syscall9 will still work, you just tell it the number of arguments is 7). This way also works with Linux shared libraries, as well, if you're targeting linux:
A sample program that calls Windows DLLs from Go:
package main
import (
"fmt"
"syscall"
"unsafe"
)
func abort(funcname string, err error) {
panic(fmt.Sprintf("%s failed: %v", funcname, err))
}
var (
kernel32, _ = syscall.LoadLibrary("kernel32.dll")
getModuleHandle, _ = syscall.GetProcAddress(kernel32, "GetModuleHandleW")
user32, _ = syscall.LoadLibrary("user32.dll")
messageBox, _ = syscall.GetProcAddress(user32, "MessageBoxW")
)
const (
MB_OK = 0x00000000
MB_OKCANCEL = 0x00000001
MB_ABORTRETRYIGNORE = 0x00000002
MB_YESNOCANCEL = 0x00000003
MB_YESNO = 0x00000004
MB_RETRYCANCEL = 0x00000005
MB_CANCELTRYCONTINUE = 0x00000006
MB_ICONHAND = 0x00000010
MB_ICONQUESTION = 0x00000020
MB_ICONEXCLAMATION = 0x00000030
MB_ICONASTERISK = 0x00000040
MB_USERICON = 0x00000080
MB_ICONWARNING = MB_ICONEXCLAMATION
MB_ICONERROR = MB_ICONHAND
MB_ICONINFORMATION = MB_ICONASTERISK
MB_ICONSTOP = MB_ICONHAND
MB_DEFBUTTON1 = 0x00000000
MB_DEFBUTTON2 = 0x00000100
MB_DEFBUTTON3 = 0x00000200
MB_DEFBUTTON4 = 0x00000300
)
func MessageBox(caption, text string, style uintptr) (result int) {
var nargs uintptr = 4
ret, _, callErr := syscall.Syscall9(uintptr(messageBox),
nargs,
0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
style,
0,
0,
0,
0,
0)
if callErr != 0 {
abort("Call MessageBox", callErr)
}
result = int(ret)
return
}
func GetModuleHandle() (handle uintptr) {
var nargs uintptr = 0
if ret, _, callErr := syscall.Syscall(uintptr(getModuleHandle), nargs, 0, 0, 0); callErr != 0 {
abort("Call GetModuleHandle", callErr)
} else {
handle = ret
}
return
}
func main() {
defer syscall.FreeLibrary(kernel32)
defer syscall.FreeLibrary(user32)
fmt.Printf("Return: %d\n", MessageBox("Done Title", "This test is Done.", MB_YESNOCANCEL))
}
func init() {
fmt.Print("Starting Up\n")
}
Second way is via syscall.NewProc (etc.) instead of syscall.GetProcAddress. These are basically some helper methods over the syscall ones, you saw above, and are available in Windows only: http://golang.org/src/pkg/syscall/dll_windows.go
package main
import (
"fmt"
"syscall"
"unsafe"
)
func main() {
var mod = syscall.NewLazyDLL("user32.dll")
var proc = mod.NewProc("MessageBoxW")
var MB_YESNOCANCEL = 0x00000003
ret, _, _ := proc.Call(0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Done Title"))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("This test is Done."))),
uintptr(MB_YESNOCANCEL))
fmt.Printf("Return: %d\n", ret)
}
A third way would be to call into libraries basically by "linking" against the library, using the "cgo" method (this way works in Linux and Windows):
This way would look something like this
import ("C")
...
C.MessageBoxW(...)
See cgo for further details.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.