GreenBox 0 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 Share this post Link to post Share on other sites
GreenBox 0 Posted March 13, 2011 just error by space char ' '... Share this post Link to post Share on other sites