Ilya Bobir wrote:
Hello.

I'm new to this thread, so please excuse me if this already been discussed or have already been patched.

While working with COM I've noticed that sometimes Python long values does not convert correctly to COM VARIANT (I assumed that VT_{I4,UI4,I8,UI8,BSTR} should be used). I was able to workaround this problem in my case, but later, after reading conversion source, I've came to conclusion that it is possible to write a better conversion for this case (long -> VARIANT). Here is goes.

This source was not tested, not even been compiled, because I don't have set environment to build and test. This is a draft that, I believe, could be of some use to someone else.
Reference counter should be decreased.
*** oleargs.cpp.orig    Mon Jul 21 20:48:10 1997
--- oleargs.cpp Fri May  5 18:55:56 2006
***************
*** 37,59 ****
        }
        else if (PyLong_Check(obj))
        {
!               double dval = PyLong_AsDouble(obj);
!               BOOL isDword = FALSE;
!               if (dval >= 0 && dval < (double)ULONG_MAX)
                {
!                       DWORD dwval = (DWORD)dval;
!                       if ((double)dwval == dval)
!                       {
                                V_VT(var) = VT_I4;
!                               V_I4(var) = dwval;
!                               isDword = TRUE;
                        }
                }
!               if (!isDword)
!               {
!                       V_VT(var) = VT_R8;
!                       V_R8(var) = dval;
                }
        }
        else if (PyFloat_Check(obj))
        {
--- 37,112 ----
        }
        else if (PyLong_Check(obj))
        {
!               PyObject *exc_type = 0;
!               PyObject *exc_value = 0;
!               PyObject *exc_traceback = 0;
! 
!               if(PyErr_Occured())
!                       PyErr_Fetch(&exc_type, &exc_value, &exc_traceback);
! 
!               bool converted = false;
! 
                {
!                       PyErr_Clear();
!                       long v = PyLong_AsLong(obj);
!                       if(!PyErr_Occured()){
                                V_VT(var) = VT_I4;
!                               V_I4(var) = v;
!                               converted = true;
                        }
                }
! 
!               if(!converted){
!                       PyErr_Clear();
!                       unsigned long v = PyLong_AsUnsignedLong(obj);
!                       if(!PyErr_Occured()){
!                               V_VT(var) = VT_UI4;
!                               V_UI4(var) = v;
!                               converted = true;
!                       }
!               }
! 
!               if(!converted){
!                       PyErr_Clear();
!                       long long v = PyLong_AsLongLong(obj);
!                       if(!PyErr_Occured()){
!                               V_VT(var) = VT_I8;
!                               V_I8(var) = v;
!                               converted = true;
!                       }
                }
+ 
+               if(!converted){
+                       PyErr_Clear();
+                       unsigned long long v = PyLong_AsUnsignedLongLong(obj);
+                       if(!PyErr_Occured()){
+                               V_VT(var) = VT_UI8;
+                               V_UI8(var) = v;
+                               converted = true;
+                       }
+               }
+ 
+               if(!converted){
+                       PyErr_Clear();
+                       PyStringObject *pyV = static_cast<PyStringObject 
*>(long_format(obj, 10, 0));
+                       if(!PyErr_Occured() && pyV){
+                               char *v = PyString_AS_STRING(pyV);
+                               BSTR wv = SysAllocStringLen(0, 
PyString_GET_SIZE(pyV));
+                               for(int i = 0; i < PyString_GET_SIZE(pyV); ++i)
+                                       wv[i] = v[i];
+                               wv[PyString_GET_SIZE(pyV)] = 0;
+ 
+                               V_VT(var) = VT_BSTR;
+                               V_BSTR(var) = wv;
+ 
+                               Py_DECREF(pyV);
+                       }
+               }
+ 
+               if(exc_type)
+                       PyErr_Restore(exc_type, exc_value, exc_traceback);
+               else
+                       PyErr_Clear();
        }
        else if (PyFloat_Check(obj))
        {
_______________________________________________
Python-win32 mailing list
Python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to