golang 호출 dll

2238 단어
//호출 방법
func WindowVersion1() {
	h, err := syscall.LoadLibrary("kernel32.dll")
	if err != nil {
		fmt.Printf("Error: %s
", err) return } defer syscall.FreeLibrary(h) proc, err := syscall.GetProcAddress(h, "GetVersion") if err != nil { fmt.Printf("Error: %s
", err) return } r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0, 0) major := byte(r) minor := uint8(r >> 8) build := uint16(r >> 16) print("windows version ", major, ".", minor, " (Build ", build, ")
") } func WindowVersion2() { dll32 := syscall.NewLazyDLL("kernel32.dll") g := dll32.NewProc("GetVersion") r, _, _ := g.Call() major := byte(r) minor := uint8(r >> 8) build := uint16(r >> 16) print("windows version ", major, ".", minor, " (Build ", build, ")
") }

//c++ dll 호출
사용 시 go가 생성한exe와 c++가 생성한 dll를 같은 디렉터리에 두면 됩니다.
C++:
//vs 2010, c++ 포함::MessageBox(NULL,str, T("..."), MB OK);디버깅을 사용할 때 프로그램 충돌을 일으킬 수 있습니다.
//dlltest.h
DLL_API int __stdcall test1(LPTSTR s);
DLL_API int __stdcall test2(int *m);

//dlltest.cpp
int __stdcall test1(LPTSTR s)
{
	CStringA sz(s);
	cout<<sz<<endl;
	return 0;
}

int __stdcall test2(int *m)
{
	*m=*m*3+1;
	return 123;
}

go:
func callDll1() {
	dll32 := syscall.NewLazyDLL("dlltest.dll")
	fmt.Println("dll name:", dll32.Name)

	g := dll32.NewProc("_test1@4")
	s := "1k  fd"

	r1, _, _ := g.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s))))
	fmt.Println("callDll1  :", r1)
}

func callDll2() {
	dll32 := syscall.NewLazyDLL("dlltest.dll")

	g := dll32.NewProc("_test2@4")

	var m int32
	m = 10
	p := &m
	fmt.Printf("%#v
", p) r1, _, _ := g.Call(uintptr(unsafe.Pointer(p))) fmt.Println("callDll2 :", (int32)(r1)) // m fmt.Println(*(*int32)(unsafe.Pointer(p))) // 31 }

dll에서 *string 오류 원인을 되돌려 보냅니다: golang의string은struct가len판단으로 끝났고 c/c++의string은'\0'으로 끝났습니다.밑바닥 데이터의 결과가 다르기 때문에따라서 dll을 사용하여 전송된 데이터를 전송할 때 밑바닥 데이터 형식의 일치성 문제를 조심해야 한다.

좋은 웹페이지 즐겨찾기