回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我目前正在进入<code>ctypes</code>模块,并尝试使用<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499%28v=vs.85%29.aspx" rel="nofollow">^{<cd4>}</a>接收到的<code>HWND</code>句柄调用user32函数<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633520%28v=vs.85%29.aspx" rel="nofollow">^{<cd2>}</a>。这一次我想更进一步,使用函数原型,而不是用<code>ctypes.windll.user32.GetWindowText</code>调用函数。尽管我在将<code>lpString</code>参数声明为输出参数时遇到问题。在</p>
<p>我的第一次尝试是这样的:</p>
<pre><code>GetWindowText = cfunc("GetWindowTextA",windll.user32,c_int,
("hWnd",HWND,1),
("lpString",LPCSTR,2),
("nMaxCount",c_int,1)
)
</code></pre>
<p>(<code>cfunc</code>是我找到的一个小包装器<a href="http://www.cs.unc.edu/~gb/blog/2007/02/11/ctypes-tricks/" rel="nofollow">here</a>)</p>
<p>一旦调用此原型,就会产生以下异常:</p>
^{pr2}$
<p>我认为任何输出变量都必须是<code>POINTER(...)</code>类型,因此我将定义改为:</p>
<pre><code>GetWindowText = cfunc("GetWindowTextA",windll.user32,c_int,
("hWnd",HWND,1),
("lpString",POINTER(c_char),2),
("nMaxCount",c_int,1)
)
</code></pre>
<p>但这也产生了一个例外:</p>
<pre><code> chars,name = user32.GetWindowText(handle,255)
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type
</code></pre>
<p>我希望有人知道如何使用<code>ctypes</code>原型来正确调用<code>GetWindowText</code>函数。在</p>
<p><strong>编辑:</strong></p>
<p>通过进一步的研究,我至少可以让它发挥作用。我修复的第一个问题是<code>cfunc()</code>的用法,它有错误的调用说明符。我定义了该函数的精确副本,并将其命名为<code>winfunc()</code>,并将<code>return CFUNCTYPE(result, *atypes)((name, dll), tuple(aflags))</code>替换为<code>return WINFUNCTYPE(result, *atypes)((name, dll), tuple(aflags))</code>。在</p>
<p>然后我进一步检查了原型。看起来,如果您将<code>("someParameter",POINTER(aType),2)</code>传递给<code>WINFUNCTYPE</code>,它将在调用时创建一个<code>aType</code>对象,并将指向该对象的指针传递给函数。在返回的元组中,您可以访问<code>aType</code>对象。这带来了另一个问题。cstring是一个字符数组;因此需要告诉ctypes创建一个<code>c_char array</code>。这意味着:</p>
<pre><code>GetWindowText = winfunc("GetWindowTextA",windll.user32,c_int,
("hWnd",HWND,1),
("lpString",POINTER(c_char*255),2),
("nMaxCount",c_int,1)
)
</code></pre>
<p>很好用。但不幸的是,ctypes现在将传递一个指向cstring的指针,该指针总是255个字符长,忽略了<code>nMaxCount</code>指定的大小。在</p>
<p>在我看来,我认为没有办法让这个函数与定义为输出参数的动态大小的cstring一起工作。唯一的可能性似乎是不使用输出参数特性,而将<code>LPCSTR</code>定义为输入参数。然后被调用者需要用<code>ctypes.create_string_buffer()</code>自己创建一个缓冲区,并将其传递给函数(就像在C中一样)。在</p>