Skip to content

Commit adb8ac9

Browse files
author
g.ph
committed
update
0 parents  commit adb8ac9

File tree

6 files changed

+272
-0
lines changed

6 files changed

+272
-0
lines changed

cfuncs.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package cpy3
2+
3+
import (
4+
"syscall"
5+
"unsafe"
6+
)
7+
8+
type Pointer = uintptr
9+
type SIZE_T = uintptr
10+
11+
const sizeOfUintPtr = unsafe.Sizeof(uintptr(0))
12+
13+
func uintptrToBytes(u uintptr) []byte {
14+
return (*[sizeOfUintPtr]byte)(unsafe.Pointer(u))[:]
15+
}
16+
17+
//func CStrToGoStr(ustr uintptr)string{
18+
// return copyStr(ustr,G_strlen(ustr))
19+
//}
20+
21+
func CBytesToGoBytes(ustr uintptr, n int) []byte {
22+
return copyBytes(ustr, n)
23+
}
24+
25+
// 这种跟copyStr3基本一样,只是用go来处理了
26+
func copyBytes(src uintptr, strLen int) []byte {
27+
if strLen == 0 {
28+
return nil
29+
}
30+
str := make([]byte, strLen)
31+
for i := 0; i < strLen; i++ {
32+
str[i] = *(*byte)(unsafe.Pointer(src + uintptr(i)))
33+
}
34+
return str
35+
}
36+
37+
// 这种跟copyStr3基本一样,只是用go来处理了
38+
func copyStr(src uintptr, strLen int) string {
39+
if strLen == 0 {
40+
return ""
41+
}
42+
str := make([]uint8, strLen)
43+
for i := 0; i < strLen; i++ {
44+
str[i] = *(*uint8)(unsafe.Pointer(src + uintptr(i)))
45+
}
46+
return string(str)
47+
}
48+
49+
// Go的string转换为Lazarus的string
50+
func GoStrToCStr(s string) uintptr {
51+
if s == "" {
52+
return 0
53+
}
54+
return uintptr(unsafe.Pointer(StringToUTF8Ptr(s)))
55+
}
56+
57+
// Go的string转换为Lazarus的string
58+
func GoByteToCPtr(b []byte) uintptr {
59+
if len(b) == 0 {
60+
return 0
61+
}
62+
return uintptr(unsafe.Pointer(&b[0]))
63+
}
64+
65+
// 字符串到UTF8指针
66+
func StringToUTF8Ptr(s string) *uint8 {
67+
temp := []byte(s)
68+
utf8StrArr := make([]uint8, len(temp)+1) // +1是因为Lazarus中PChar为0结尾
69+
copy(utf8StrArr, temp)
70+
return &utf8StrArr[0]
71+
}
72+
73+
// 字符串到UTF16指针
74+
func StringToUTF16Ptr(s string) uintptr {
75+
p, _ := syscall.UTF16PtrFromString(s)
76+
return uintptr(unsafe.Pointer(p))
77+
}
78+
79+
// UTF16指针到字符串
80+
func UTF16PtrToString(p uintptr) string {
81+
l := LstrlenW(p)
82+
if l == 0 {
83+
return ""
84+
}
85+
buff := make([]uint16, l)
86+
Memcpy(uintptr(unsafe.Pointer(&buff[0])), p, uintptr(l*2))
87+
return syscall.UTF16ToString(buff)
88+
}
89+
90+
func LstrlenW(lpString uintptr) int32 {
91+
r, _, _ := _lstrlenW.Call(lpString)
92+
return int32(r)
93+
}
94+
func Lstrlen(lpString uintptr) int32 {
95+
r, _, _ := _lstrlen.Call(lpString)
96+
return int32(r)
97+
}
98+
func Memcpy(dest, src Pointer, count SIZE_T) Pointer {
99+
r, _, _ := _memcpy.Call(dest, src, count)
100+
return r
101+
}

cpy3.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package cpy3
2+
3+
import "unsafe"
4+
5+
func Py_Initialize() {
6+
py_Initialize.Call()
7+
}
8+
func Py_InitializeEx(initsigs int) {
9+
py_Initialize.Call(uintptr(initsigs))
10+
}
11+
func Py_IsInitialized() int {
12+
r, _, _ := py_IsInitialized.Call()
13+
return int(r)
14+
}
15+
func Py_Finalize() {
16+
py_Finalize.Call()
17+
}
18+
func Py_FinalizeEx() int {
19+
r, _, _ := py_FinalizeEx.Call()
20+
return int(r)
21+
}
22+
23+
func Py_DecodeLocale(arg string, size uintptr) string {
24+
r, _, _ := py_DecodeLocale.Call(GoStrToCStr(arg), size)
25+
defer PyMem_RawFree(r)
26+
return UTF16PtrToString(r)
27+
}
28+
func PyMem_Free(obj uintptr) {
29+
pyMem_Free.Call(obj)
30+
}
31+
func PyMem_RawFree(obj uintptr) {
32+
pyMem_RawFree.Call(obj)
33+
}
34+
35+
func Py_Main(args []string) int {
36+
argc := len(args)
37+
argv := make([]uintptr, 0)
38+
for _, arg := range args {
39+
argv = append(argv, StringToUTF16Ptr(arg))
40+
}
41+
r, _, _ := py_BytesMain.Call(uintptr(argc), uintptr(unsafe.Pointer(&argv[0])))
42+
return int(r)
43+
}
44+
func Py_BytesMain(args []string) int {
45+
argc := len(args)
46+
r, _, _ := py_BytesMain.Call(uintptr(argc))
47+
return int(r)
48+
}
49+
50+
func PyRun_AnyFile(fp uintptr, filename string) int {
51+
r, _, _ := pyRun_AnyFile.Call(uintptr(fp), GoStrToCStr(filename))
52+
return int(r)
53+
}
54+
func PyRun_SimpleFile(fp uintptr, filename string) int {
55+
r, _, _ := pyRun_SimpleFile.Call(uintptr(fp), GoStrToCStr(filename))
56+
return int(r)
57+
}
58+
func PyRun_SimpleString(command string) int {
59+
r, _, _ := pyRun_SimpleString.Call(GoStrToCStr(command))
60+
return int(r)
61+
}
62+
63+
func Py_SetProgramName(name string) {
64+
py_SetProgramName.Call(StringToUTF16Ptr(name))
65+
}
66+
func Py_GetProgramName() string {
67+
r, _, _ := py_GetProgramName.Call()
68+
return UTF16PtrToString(r)
69+
}
70+
71+
func Py_SetPath(path string) {
72+
py_SetPath.Call(StringToUTF16Ptr(path))
73+
}
74+
75+
func Py_SetPythonHome(home string) {
76+
py_SetPythonHome.Call(StringToUTF16Ptr(home))
77+
}

dylib_nontempdll.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//go:build !tempdll && !memorydll
2+
// +build !tempdll,!memorydll
3+
4+
package cpy3
5+
6+
func checkAndReleaseDLL() (bool, string) {
7+
return false, ""
8+
}

dylib_tempdll.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build (windows || linux || darwin) && tempdll
2+
// +build windows linux darwin
3+
// +build tempdll
4+
5+
package cpy3
6+
7+
func checkAndReleaseDLL() (bool, string) {
8+
return false, ""
9+
}

importfuncs.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package cpy3
2+
3+
import "syscall"
4+
5+
var (
6+
py_Initialize = libpython3.NewProc("Py_Initialize")
7+
py_InitializeEx = libpython3.NewProc("Py_InitializeEx")
8+
py_IsInitialized = libpython3.NewProc("Py_IsInitialized")
9+
py_Finalize = libpython3.NewProc("Py_Finalize")
10+
py_FinalizeEx = libpython3.NewProc("Py_FinalizeEx")
11+
py_DecodeLocale = libpython3.NewProc("Py_DecodeLocale")
12+
pyMem_Free = libpython3.NewProc("PyMem_Free")
13+
pyMem_RawFree = libpython3.NewProc("PyMem_RawFree")
14+
15+
py_SetProgramName = libpython3.NewProc("Py_SetProgramName")
16+
py_GetProgramName = libpython3.NewProc("Py_GetProgramName")
17+
pyEval_ThreadsInitialized = libpython3.NewProc("PyEval_ThreadsInitialized")
18+
py_Main = libpython3.NewProc("Py_Main")
19+
py_BytesMain = libpython3.NewProc("Py_BytesMain")
20+
pyRun_AnyFile = libpython3.NewProc("PyRun_AnyFile")
21+
pyRun_SimpleFile = libpython3.NewProc("PyRun_SimpleFile")
22+
pyRun_SimpleString = libpython3.NewProc("PyRun_SimpleString")
23+
py_SetPath = libpython3.NewProc("Py_SetPath")
24+
py_SetPythonHome = libpython3.NewProc("Py_SetPythonHome")
25+
)
26+
var kernel32dll = syscall.NewLazyDLL("kernel32.dll")
27+
var (
28+
_lstrlenW = kernel32dll.NewProc("lstrlenW")
29+
_lstrlen = kernel32dll.NewProc("lstrlenA")
30+
)
31+
32+
var msvcrtdll = syscall.NewLazyDLL("msvcrt.dll")
33+
var (
34+
_memcpy = msvcrtdll.NewProc("memcpy")
35+
)

loadlib.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package cpy3
2+
3+
import (
4+
"github.com/aadog/dylib"
5+
"runtime"
6+
)
7+
8+
var libpython3 = loadUILib()
9+
10+
var (
11+
platformExtNames = map[string]string{
12+
"windows": ".dll",
13+
"linux": ".so",
14+
"darwin": ".dylib",
15+
}
16+
)
17+
18+
// 加载库
19+
func loadUILib() *dylib.LazyDLL {
20+
libName := getDLLName()
21+
// 如果支持运行时释放,则使用此种方法
22+
if support, newDLLPath := checkAndReleaseDLL(); support {
23+
libName = newDLLPath
24+
} else {
25+
libName = libName
26+
}
27+
lib := dylib.NewLazyDLL(libName)
28+
err := lib.Load()
29+
if err != nil {
30+
panic(err)
31+
}
32+
33+
return lib
34+
}
35+
36+
func getDLLName() string {
37+
libName := "python310"
38+
if ext, ok := platformExtNames[runtime.GOOS]; ok {
39+
return libName + ext
40+
}
41+
return libName
42+
}

0 commit comments

Comments
 (0)