golang 編寫 dll 給別的語言調用

// func.go
package main

import "C"
import "fmt"

//export Add
func Add(a C.int, b C.int) C.int {
	return a + b
}

//export Print
func Print(s *C.char) {  
/* 
函數參數可以用 string, 但是用*C.char更通用一些。
由於string的數據結構,是可以被其它go程序調用的,
但其它語言(如 python)就不行了
*/
	print("Hello ", C.GoString(s)) //這裏不能用fmt包,會報錯,調了很久...
}
func main() {	
}
  • 編譯
    go build -ldflags "-s -w" -buildmode=c-shared -o func.dll func.go
    還是有點大的,880KB,純C 編譯的只有48KB,應該是沒有包含全部的依賴吧,go是全包進來了

Go 調用

package main
import (
	"fmt"
	"syscall"
)

func main() {
	dll := syscall.NewLazyDLL("func.dll")
	add := dll.NewProc("Add")
	prt := dll.NewProc("Print")
	r, err, msg := add.Call(32, 44)
	fmt.Println(r)
	fmt.Println(err)
	fmt.Println(msg)
	
	name := C.CString("Andy")
	prt.Call(uintptr(unsafe.Pointer(name)))
}

out:
76
0
The operation completed successfully.
Hello Andy

Python 調用

from ctypes import CDLL, c_char_p
dll = CDLL("func.dll")
dll.Add(32, 33)
dll.Print(c_char_p(bytes("Andy", "utf8")))

C++調用

#include <iostream>
#include <windows.h>

using namespace std;
typedef int(*pAdd)(int a, int b);
typedef void(*pPrt)(char* s);

int main(int argc, char *argv[])
{
    HMODULE dll= LoadLibraryA("func.dll");
    pAdd add = (pAdd)GetProcAddress(dll, "Add");
    pPrt prt = (pPrt)GetProcAddress(dll, "Print");
    cout << add(321, 33) << endl;
    prt("Andy");
    FreeLibrary(dll);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章