GreenBox Posted March 1, 2011 Posted March 1, 2011 (edited) I'm sorry my english... i try DllCallbackRegister($func, "ptr:cdecl", "ptr; ptr") but it's raise error when callback called. only use can DllCallbackRegister($func, "ptr:cdecl", "ptr") but no idea how get param from python... help please. output: E:\Users\EcmaXp\Desktop>python32 ./module1.py <module 'spam' (built-in)> ['__doc__', '__name__', '__package__', 'hello' <built-in function hello> hello 3 <module 'spam' (built-in)> E:\Users\EcmaXp\Desktop>rem after compile change to DllCallbackRegister($func, "ptr:cdecl", "ptr; ptr") E:\Users\EcmaXp\Desktop>python32 ./module1.py <module 'spam' (built-in)> ['__doc__', '__name__', '__package__', 'hello' <built-in function hello> E:\Users\EcmaXp\Desktop>rem error! E:\Users\EcmaXp\Desktop> code: expandcollapse popup; Python 3.1 <=> Autoit 3 #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #NoTrayIcon #include <misc.au3> #include <string.au3> Global $_NON_FREE_STRUCT[1] Global $_current_line = -1 Global $_Py_AutoitDebug = False Global $_Py_AutoitMaxiumArgmentCount = 4 Global Const $PYTHON_API_VERSION = 1013 Global Const $tagPyObject = _ "long_ptr ob_refcnt;" & _ ; long_ptr is a ssize_t is a Py_ssize_t "ptr ob_type;" Global Const $tagPyCFunctionObject = _ $tagPyObject & _ ; PyObject_HEAD "ptr m_ml;" & _ ; PyObject /* Description of the C function to call */ "ptr m_self;" & _ ; PyObject /* Passed as 'self' arg to the C func, can be NULL */ "ptr m_module;" ; PyObject /* The __module__ attribute, can be anything */ Global Const $tagPyModuleDef_Base = _ $tagPyObject & _ ; PyObject_HEAD "ptr m_init;" & _ ; PyObject* (*m_init)(void) "long_ptr m_index;" & _ ; PyObject "ptr m_copy;" ; PyObject Global Const $tagPyModuleDef = _ $tagPyModuleDef_Base & _ ; PyObject_HEAD "ptr m_name;" & _ ; const char* "ptr m_doc;" & _ ; const char* "long_ptr m_size;" & _ ; Py_ssize_t "ptr m_methods;" & _ ; PyMethodDef "ptr m_reload;" & _ ; inquiry "ptr m_traverse;" & _ ; traverseproc "ptr m_clear;" & _ ; inquiry "ptr m_free;" ; freefunc Global Const $tagPyMethodDef = _ "ptr ml_name;" & _ ; char[] /* The name of the built-in function/method */ "ptr ml_meth;" & _ ; PyCFunction /* The C function that implements it */ "int ml_flags;" & _ ; /* Combination of METH_xxx flags, which mostly describe the args expected by the C func */ "ptr ml_doc;" ; /* The __doc__ attribute, or NULL */ Global Const $Py_NULL = Ptr(0) Global Const $METH_VARARGS = 0x0001 Global Const $METH_KEYWORDS = 0x0002 Global Const $METH_NOARGS = 0x0004 Global Const $METH_O = 0x0008 Global Const $METH_CLASS = 0x0010 Global Const $METH_STATIC = 0x0020 Global Const $METH_COEXIST = 0x0040 Func PyAu_MakePyMethodDef($funcname, $pycfunction, $doc="");, $flag=$METH_VARARGS, $doc="") $assign_data = True If Not StringLen($funcname) And Not StringLen($pycfunction) Then $assign_data = False EndIf If $assign_data Then #cs $callbackarg = "" If BitAnd($flag, $METH_VARARGS) Then $callbackarg = "ptr; ptr" EndIf If BitAnd($flag, $METH_KEYWORDS) Then $callbackarg = "ptr; ptr; ptr;" EndIf If BitAnd($flag, $METH_NOARGS) Then $callbackarg = "ptr; ptr; ptr;" EndIf #ce $flag = $METH_VARARGS $callbackfunc = DllCallbackRegister($pycfunction, "ptr:cdecl", "ptr") ; THIS LINE ; I went get two param but Autoit raise error! ; how can i work? EndIf $pymethod = DllStructCreate($tagPyMethodDef) If $assign_data Then DllStructSetData($pymethod, "ml_name", MakeStringBuffer($funcname)) DllStructSetData($pymethod, "ml_meth", DllCallbackGetPtr($callbackfunc)) DllStructSetData($pymethod, "ml_flags", $flag) DllStructSetData($pymethod, "ml_doc", _Iif(StringLen($doc), MakeUnicodeBuffer($doc), $Py_NULL)) EndIf NonFreeStruct($pymethod) Return $pymethod EndFunc #cs Func PyAu_MakeCFunctionObject($func, $self=$Py_NULL, $module=$Py_NULL) $pycfunctionobj = DllStructCreate($tagPyCFunctionObject) DllStructSetData($pycfunctionobj, "m_ml", DllCallbackGetPtr($callbackfunc)) DllStructSetData($pycfunctionobj, "m_self", $self) DllStructSetData($pycfunctionobj, "m_module", $module) NonFreeStruct($pycfunctionobj) Return DllStructGetPtr($pycfunctionobj) EndFunc #ce #Region user code $PyDLL = DllOpen("python31") Func TestFunction($mod, $args) print("hello") Return $mod #cs $result = PyArg_ParseTuple($args, "ii", "int", "int") If Not IsArray($result) Then Return print("called testfuncion!") Return Py_BuildValue("i", "int", $result[1] + $result[2]) #ce EndFunc Func PyInit_spam() $a = PyAu_MakePyMethodDef("hello", "TestFunction") $b = PyAu_MakePyMethodDef("", "") $pymethods = ConcatStruct($a, $b) $pymodule = DllStructCreate($tagPyModuleDef) DllStructSetData($pymodule, "m_name", MakeStringBuffer("spam")) DllStructSetData($pymodule, "m_size", -1) DllStructSetData($pymodule, "m_methods", GetFreezeStructPtr($pymethods)) Return PyModule_Create(GetFreezeStructPtr($pymodule)) EndFunc $initfunc = DllCallbackRegister("PyInit_spam", "ptr", "") Py("Import_AppendInittab", "none", "ptr", MakeStringBuffer("spam"), "ptr", DllCallbackGetPtr($initfunc)) Py_Initialize() Global Const $Py_None = Py_GetNone() Py_Main() Py_Finalize() #EndRegion user code #Region python functions Func Py_Initialize() Py("_Initialize", "none") EndFunc ;==>Py_Initialize Func Py_GetNone() Local Static $Py_None = -1 If $Py_None == -1 Then $module = PyImport_ImportModule("builtins") $moduledict = PyModule_GetDict($module) $Py_None = PyDict_GetItem($moduledict, Py_BuildString("None")) EndIf Py_INCREF($Py_None) Return $Py_None EndFunc Func PyImport_ImportModule($name) Return Py("Import_ImportModule", "ptr", "ptr", MakeStringBuffer(String($name))) EndFunc Func Py_IsInitialized() Return Py("_IsInitialized", "int") EndFunc ;==>Py_IsInitialized Func Py_Finalize() Return Py("_Finalize", "none") EndFunc ;==>Py_Finalize Func Py_Module_New($name) Return Py("Module_New", "ptr", "ptr", MakeStringBuffer(String($name))) EndFunc ;==>Py_Module_New Func PyModule_GetDict($module) Return Py("Module_GetDict", "ptr", "ptr", $module) EndFunc ;==>PyModule_GetDict Func Py_BuildString($string) Return Py_BuildValue("s", "ptr", MakeStringBuffer($string)) EndFunc ;==>Py_BuildString Func PyImport_GetModuleDict() Return Py("Import_GetModuleDict", "ptr") EndFunc ;==>PyImport_GetModuleDict Func PyDict_SetItem($dict, $key, $value) Return Py("Dict_SetItem", "int", "ptr", $dict, "ptr", $key, "ptr", $value) EndFunc ;==>PyDict_SetItem Func PyDict_GetItem($dict, $key) Return Py("Dict_GetItem", "ptr", "ptr", $dict, "ptr", $key) EndFunc ;==>PyDict_SetItem Func PyModule_Create($module) Return PyModule_Create2($module, $PYTHON_API_VERSION) EndFunc Func PyModule_Create2($moduledef, $apiver) Return Py("Module_Create2", "ptr", "ptr", $moduledef, "int", $apiver) EndFunc Func Py_INCREF($objptr) $obj = DllStructCreate($tagPyObject, $objptr) DllStructSetData($obj, "ob_refcnt", DllStructGetData($obj, "ob_refcnt") + 1) If $_Py_AutoitDebug Then print("current(irc) : " & DllStructGetData($obj, "ob_refcnt")) EndIf EndFunc ;==>Py_INCREF Func Py_DECREF($objptr) $obj = DllStructCreate($tagPyObject, $objptr) DllStructSetData($obj, "ob_refcnt", DllStructGetData($obj, "ob_refcnt") - 1) If $_Py_AutoitDebug Then print("current(dec) : " & DllStructGetData($obj, "ob_refcnt")) EndIf EndFunc ;==>Py_DECREF Func Py_BuildValue($valueformat, _ $T1 = "", $P1 = "", _ $T2 = "", $P2 = "", _ $T3 = "", $P3 = "", _ $T4 = "", $P4 = "", _ $line = @ScriptLineNumber) If Not Mod(@NumParams, 2) Then _Py_AutoitInteralError("Wrong Argment Given") Return EndIf $paramtempformat = "" For $i = 1 To Int(@NumParams / 2) $paramformat = Eval("T" & $i) $param = Eval("P" & $i) $paramtempformat &= $paramformat & ";" Next $va_list = DllStructCreate($paramtempformat) For $i = 1 To Int(@NumParams / 2) $param = Eval("P" & $i) DllStructSetData($va_list, $i, $param) Next $result = Py("_VaBuildValue", "ptr", "str", $valueformat, "ptr", DllStructGetPtr($va_list)) $va_list = 0 Return $result EndFunc ;==>Py_BuildValue Func PyArg_ParseTuple($valueformat, _ $T1 = "", _ $T2 = "", _ $T3 = "", _ $T4 = "", _ $line = @ScriptLineNumber) For $i = 1 to $_Py_AutoitMaxiumArgmentCount If Not IsDeclared("T" & $i) Then If @NumParams > ($i + 1) Then _Py_AutoitInteralError("Wrong Argment Given") Return EndIf EndIf Next Local $resultvalue[@NumParams] $resultvalue[0] = @NumParams - 1 $paramtempformat = "" For $i = 1 To $resultvalue[0] $paramformat = Eval("T" & $i) $paramtempformat &= $paramformat & ";" Next $va_list = DllStructCreate($paramtempformat) $result = Py("Arg_VaParse", "int", "str", $valueformat, "ptr", DllStructGetPtr($va_list)) If Not $result Then Return False EndIf $va_list = 0 For $i = 1 To $resultvalue[0] $param = Eval("P" & $i) $resultvalue[$i] = DllStructGetData($va_list, $i) Next Return $resultvalue EndFunc Func Py_Main() $argc = $CmdLine[0] + 1 $argv = DllStructCreate(StringTrimRight(_StringRepeat("ptr;", $argc), 1)) DllStructSetData($argv, 1, MakeUnicodeBuffer(@ScriptFullPath)) For $i = 2 To $argc DllStructSetData($argv, $i, MakeUnicodeBuffer($CmdLine[$i - 1])) Next Py("_Main", "none", "int", $argc, "ptr", DllStructGetPtr($argv)) $argv = 0 EndFunc ;==>Py_Main #EndRegion python functions #Region help functions Func print($arg) ConsoleWrite($arg & @CRLF) EndFunc ;==>print Func NonFreeStruct(ByRef $x) Global $_NON_FREE_STRUCT $size = UBound($_NON_FREE_STRUCT) ReDim $_NON_FREE_STRUCT[$size + 1] $_NON_FREE_STRUCT[$size] = $x EndFunc ;==>NonFreeStruct Func CleanLastStruct($number = 1) Global $_NON_FREE_STRUCT $size = UBound($_NON_FREE_STRUCT) For $i = 1 To $number $_NON_FREE_STRUCT[$size] = 0 ReDim $_NON_FREE_STRUCT[$size - 1] $size -= 1 Next EndFunc ;==>CleanLastStruct Func GetStructAsByte($a) $tmp = DllStructCreate("byte [" & DllStructGetSize($a) & "]", DllStructGetPtr($a)) Return DllStructGetData($tmp, 1) EndFunc ;==>GetStructAsByte Func ConcatStruct(ByRef $a, ByRef $b) $tmp = DllStructCreate("byte a[" & DllStructGetSize($a) & "]; byte b[" & DllStructGetSize($b) & "]") DllStructSetData($tmp, 1, GetStructAsByte($a)) DllStructSetData($tmp, 2, GetStructAsByte($b)) NonFreeStruct($tmp) Return $tmp EndFunc ;==>ConcatStruct Func GetFreezeStructPtr($a) NonFreeStruct($a) Return DllStructGetPtr($a) EndFunc Func MakeStringBuffer($msg) $tmp = DllStructCreate("char[" & StringLen($msg) + 1 & "]") DllStructSetData($tmp, 1, $msg) NonFreeStruct($tmp) Return DllStructGetPtr($tmp) EndFunc ;==>MakeStringBuffer Func MakeUnicodeBuffer($msg) $tmp = DllStructCreate("wchar[" & StringLen($msg) + 1 & "]") DllStructSetData($tmp, 1, $msg) NonFreeStruct($tmp) Return DllStructGetPtr($tmp) EndFunc ;==>MakeUnicodeBuffer Func _Py_AutoitInteralError($msg, $line = $_current_line) print("Internal Error:" & $line & ": " & $msg) Exit 1 EndFunc ;==>_Py_AutoitInteralError Func _Py_AutoitInteralWarning($msg, $line = $_current_line) print("Internal Warning:" & $line & ": " & $msg) EndFunc ;==>_Py_AutoitInteralWarning Func Py($funcname, $typeret, _ $T1 = "", $P1 = "", _ $T2 = "", $P2 = "", _ $T3 = "", $P3 = "", _ $T4 = "", $P4 = "", _ $T5 = "", $P5 = "", _ $T6 = "", $P6 = "", _ $T7 = "", $P7 = "", _ $T8 = "", $P8 = "", _ $T9 = "", $P9 = "", _ $T10 = "", $P10 = "", _ $T11 = "", $P11 = "", _ $T12 = "", $P12 = "", _ $line = @ScriptLineNumber) Global $PyDLL Global $_current_line = $line $ERROR_POINTER_NULL = False If StringLen(StringStripWS($typeret, 1 + 2 + 4 + 8)) <> StringLen($typeret) Then _Py_AutoitInteralError("Return Type are have space") EndIf If $typeret == "ptr" Then $ERROR_POINTER_NULL = True EndIf $typeret &= ":cdecl" $funcname = "Py" & $funcname If @NumParams == 2 Then $ret = DllCall($PyDLL, $typeret, $funcname) ElseIf @NumParams == 4 Then $ret = DllCall($PyDLL, $typeret, $funcname, $T1, $P1) ElseIf @NumParams == 6 Then $ret = DllCall($PyDLL, $typeret, $funcname, $T1, $P1, $T2, $P2) ElseIf @NumParams == 8 Then $ret = DllCall($PyDLL, $typeret, $funcname, $T1, $P1, $T2, $P2, $T3, $P3) ElseIf @NumParams == 10 Then $ret = DllCall($PyDLL, $typeret, $funcname, $T1, $P1, $T2, $P2, $T3, $P3, $T4, $P4) ElseIf Mod(@NumParams - 3, 2) Then $ExecuteString = "DllCall($PyDLL, $typeret, $funcname" For $i = 1 To Int((@NumParams - 2) / 2) $ExecuteString &= ", $T" & $i & ", $P" & $i Next $ExecuteString &= ")" $ret = Execute($ExecuteString) Else _Py_AutoitInteralError("Wrong Argment Given") Return EndIf $err = @error $ext = @extended If $err Then Local $err_table[5] = [ _ '0 no error (unknown!)', _ '1 unable to use the DLL file', _ '2 unknown "return type"', _ '3 "function" not found in the DLL file', _ '4 bad number of parameters' _ ] _Py_AutoitInteralError("Fail Call Function (" & $funcname & ", " & $typeret & ", '" & $err_table[$err] & "', " & $ext & ")") Return EndIf If IsArray($ret) Then $ret = $ret[0] EndIf If $ERROR_POINTER_NULL And Not $ret Then _Py_AutoitInteralError("The Pointer are Null") Return EndIf If $_Py_AutoitDebug Then print("Return " & _Iif(StringLen($ret), $ret, "None") & @TAB & "From " & $_current_line & " line") EndIf Return $ret EndFunc ;==>Py #EndRegion help functions python code import spam print(spam) print(dir(spam)) print(spam.hello) print(3, spam.hello(3, 3)) Edited March 13, 2011 by GreenBox
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now