[python-win32] Byte arrays and COM
Tim Roberts
timr at probo.com
Tue Mar 2 19:51:36 CET 2010
Dave Cross wrote:
> Hi All,
>
> I'm tying myself in knots trying to pass a byte array between a
> C++ DLL and python.
More accurately, between a COM server and Python. The strategies are
somewhat different.
> The simplified IDl looks like this:
> HRESULT Test([in,out] int *len, [in,out, size_is(*len)] byte* outp);
> and the implementation does this:
> STDMETHODIMP CComTestObj::Test(int *len, unsigned char* outp)
> {
> printf("input param is <%d> %s at %lx,\n",*len, outp, outp);
> strncpy((char*)outp,"TEST",*len);
> return S_OK;
> }
> Makepy generates the following:
>
> def Test(self, len=defaultNamedNotOptArg,
> outp=defaultNamedNotOptArg):
> """method Test"""
> return self._ApplyTypes_(6, 1, (24, 0), ((16387, 3), (16401,
> 3)), u'Test', None,len, outp)
>
> I interpret (16387,3) as VT_I4, ByREF, In & Out and (16401,3) as
> VT_UI1, ByRef In & Out so this looks OK to me.
Well, sort of. Python reasonably interprets those as being "one
integer, in and out" and "one byte, in and out". It does not interpret
either one as an array. "byte *" is not a standard COM type. You can
pass strings as BSTR, or you can use a VARIANT to pass a SAFEARRAY.
That's especially true if you intend to change the string. You need to
take extra steps to do that.
> However when I call it like this:
>
> object = win32com.client.Dispatch("ComTest.ComTestObj.1")
> test = create_string_buffer("Hello")
> print "Test is ", object.Test(6,addressof(test))
> Then
> a) The C++ routine gets an address that doesn't map to the
> input string
> and b) the returned value is (3, 84)
Was that the exact code? 84 is correct, because your C code changes the
first byte "T", which is ASCII 84. I would have expected the first
parameter to be 6, however.
--
Tim Roberts, timr at probo.com
Providenza & Boekelheide, Inc.
More information about the python-win32
mailing list