저는 현재 Python 3에서 ctypes를 사용하여 Python으로 작성된 라이브러리를 래핑하는 Tcl 애플리케이션을 만들고 있습니다.
from ctypes import *
import sys
tcl = cdll.LoadLibrary("libtcl.so")
TCL_OK = 0
TCL_ERROR = 1
def say_hello(cdata: c_void_p, interp: c_void_p, argc: c_int, argv: POINTER(c_char_p)) -> int:
"This function wraps some functionality that is written in Python"
print("hello, world")
return TCL_OK
# useful type definitions
Tcl_AppInitProc = CFUNCTYPE(c_int, c_void_p)
Tcl_CmdProc = CFUNCTYPE(c_int, c_void_p, c_void_p, c_int, POINTER(c_char_p))
Tcl_CmdDeleteProc = CFUNCTYPE(None, c_int)
def app_init(interp: c_void_p) -> int:
# initialize the interpreter
tcl.Tcl_Init.restype = c_int
tcl.Tcl_Init.argtypes = [c_void_p]
if tcl.Tcl_Init(interp) == TCL_ERROR:
return TCL_ERROR
# create custom commands
tcl.Tcl_CreateCommand.restype = c_void_p
tcl.Tcl_CreateCommand.argtypes = [c_void_p, c_char_p, Tcl_CmdProc, c_int, Tcl_CmdDeleteProc]
tcl.Tcl_CreateCommand(interp, b"say_hello", Tcl_CmdProc(say_hello), 0, Tcl_CmdDeleteProc(0))
return TCL_OK
if __name__ == "__main__":
# initialize argv
Argv = c_char_p * (1 + len(sys.argv))
argv = Argv(*(bytes(arg, "utf-8") for arg in sys.argv), 0)
# summon the chief interpreter
tcl.Tcl_Main.argtypes = [c_int, POINTER(c_char_p), Tcl_AppInitProc]
tcl.Tcl_Main(len(sys.argv), argv, Tcl_AppInitProc(app_init))
명령 줄에서 이것은 추가 명령이있는 Tcl 인터프리터처럼 작동합니다. sys.argv
대화 형 셸과 Tcl 스크립트를 실행하기 위해 구문 분석 하고 작동합니다.
bash$ python3 hello.py
% say_hello
hello, world
% ls
foo.tcl hello.py
% exit
bash$ cat foo.tcl
say_hello
bash$ python3 hello.py foo.tcl
hello, world
bash$
그러나 파이썬에는 이미 tkinter 모듈에 Tcl 인터프리터가 포함되어 있다는 것을 알고 있습니다. 대신에 이미 멋진 Python으로 래핑 된 API가 있고 ctypes에 대해 약간의 혼란을 덜어 줄 수 있기 때문에 대신 사용하고 싶습니다.
인터프리터를 만들고 쉽게 명령을 추가 할 수 있습니다.
from tkinter import *
def say_hello():
print("hello, world")
if __name__ == "__main__":
tcl = Tcl()
tcl.createcommand("say_hello", say_hello)
tcl.eval("say_hello")
하지만 전화를 할 수있는 방법 찾을 수 없습니다 Tcl_Init
또는 Tcl_Main
, 그없이 나는 대화를 실행할 수 없습니다. 내가 명령 줄 파서에 대해 그렇게 많이 신경 쓰지 않지만, 그것은 그들이 같은은 Tcl 명령 (것처럼 외부 프로그램을 실행하는 것처럼, 모든 기능 파이썬에서 Tcl의 대화 형 쉘을 복제하려고 많은 노력을 할 것입니다 ls
에 위의 예). 이것이 내 유일한 옵션이라면 ctypes를 계속 사용하겠습니다.
Tkinter와 함께 제공되는 Tcl 인터프리터를 대화 형 셸로 실행할 수있는 방법이 있습니까? 해키하거나 지원되지 않는 방법이 있습니까?
에서 구현 된 REPL Tcl_Main()
은 매우 간단합니다. 몇 줄의 Tcl에서 (약간 줄인) 버전을 할 수 있습니다.
set cmd ""
set prompt "% "
while true {
# Prompt for input
puts -nonewline $prompt
flush stdout
if {[gets stdin line] < 0} break
# Handle multiline commands
append cmd $line "\n"
if {![info complete $cmd]} {
set prompt ""
continue
}
set prompt "% "
# Evaluate the command and print error/non-empty results
if {[catch $cmd msg]} {
puts stderr "Error: $msg"
} elseif {$msg ne ""} {
puts $msg
}
set cmd ""
}
여러분이해야 할 일은 파이썬 코드 내의 Tcl 인터프리터 내부에서 실행하는 것입니다. 또한 대부분의 REPL을 Python으로 다시 구현할 수 있습니다. Tcl이 실제로 필요한 유일한 부분은 info complete $cmd
(완전한 명령이 입력 버퍼에 있는지 테스트) 및 catch $cmd msg
(Tcl 인터프리터에서 입력 버퍼를 평가하고 결과 및 오류를 트래핑)하는 것입니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다