ValueError:NULL COM指针访问

时间:2013-11-29 21:42:33

标签: python ctypes winhttp

我正在尝试扩展azure WinHttpRequest python绑定以便能够修改请求选项。理想情况下,我只想通过winhttp.dll WinHttpSetOptions函数设置全局选项,但我无法弄清楚如何做到这一点。无论如何,我决定冒险尝试这种方法,但是得到了“NULL COM指针访问”错误。是否与我分配给_put_Option声明的无效序号有关?即(30, 'put_Option')或仅仅是无法找到符号?我正在使用IWinHttpRequest文档获取指导:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383998(v=vs.85).aspx

class _WinHttpRequestOption(object):
    MaxResponseHeaderSize = 15


class _WinHttpRequestExtension(_WinHttpRequest):
    _put_Option = WINFUNCTYPE(HRESULT, c_int, VARIANT)(30, 'put_Option')

    def _SetOption(self, name, value):
        logging.getLogger(self.__class__.__name__).debug(
            "SetOption %s = %s" % (name, value)
        )

        enum_name = getattr(_WinHttpRequestOption, name)

        var_value = VARIANT()
        var_value.vt = VT_I4
        var_value.vdata.lval = long(value)

        _WinHttpRequestExtension._put_Option(self, enum_name, var_value)

哦是的,设置属性的代码:

http_request = _WinHttpRequestExtension()
http_request._SetOption("MaxResponseHeaderSize", 128 * 1024)

更新

找到此链接:

https://chromium.googlesource.com/chromium/deps/perl/+/master%5E/c/i686-w64-mingw32/include/httprequestid.h

它定义了该函数的调度ID。由于我不是Windows开发人员,我不知道调度ID是什么。虽然用这个替换我的序数仍然不起作用。

#define DISPID_HTTPREQUEST_BASE 0x00000001
#define DISPID_HTTPREQUEST_OPTION (DISPID_HTTPREQUEST_BASE + 5)

_put_Option = WINFUNCTYPE(HRESULT, c_int, VARIANT)(6, 'Option')

另外

我发现了这一点,这表明self不是对正确事物的引用。查看此代码中的COM错误。 if (!this->b_ptr || *(void **)this->b_ptr == NULL) {

#ifdef MS_WIN32
if (self->index) {
    /* It's a COM method */
    CDataObject *this;
    this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
    if (!this) {
        PyErr_SetString(PyExc_ValueError,
                        "native com method call without 'this' parameter");
        return NULL;
    }
    if (!CDataObject_Check(this)) {
        PyErr_SetString(PyExc_TypeError,
                        "Expected a COM this pointer as first argument");
        return NULL;
    }
    /* there should be more checks? No, in Python */
    /* First arg is an pointer to an interface instance */
    if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
        PyErr_SetString(PyExc_ValueError,
                        "NULL COM pointer access");
        return NULL;
    }

如果我这样做,我可能会收到"Expected a COM this pointer as first argument"错误:

_WinHttpRequestExtension._put_Option(super(_WinHttpRequestExtension, self), enum_name, var_value)

1 个答案:

答案 0 :(得分:0)

最后发现我在CoInitialised()之前访问了对象上的方法。将呼叫转移到CoInitialise的呼叫之外似乎让我更进一步,但现在我得到了错误:

  

ValueError:可能使用过多参数调用过程(超过16个字节)