0

タイトルが正確でない場合は申し訳ありませんが、状況を 100% 正しく説明しているわけではありません。

Python の ctypes モジュールを使用して、FreeTDS C ライブラリとのインターフェイスを試みています。私はいくつかのコードを驚くほどうまく実行していますが、1 つの障害に遭遇しました。以下の dbbind() 呼び出しの最後のパラメーターを ctypes に変換する方法がわかりません。

私がフォローしているCの例は次のとおりです。

  /* these variable types are defined in the FreeTDS library */
  DBINT customer_id;
  DBCHAR company_name[255];
  DBFLT8 avg_income;

  /* <snip> */


  /* Now bind the returned columns to the variables */
  /* BYTE is defined in the FreeTDS library */
  dbbind(dbconn, 1, INTBIND, 0, (BYTE *)&customer_id);
  dbbind(dbconn, 2, NTBSTRINGBIND, 0, (BYTE *)&company_name);
  dbbind(dbconn, 3, FLT8BIND, 0, (BYTE*)&avg_income);

では、A) Python で自分の変数をライブラリの変数型として定義する方法と、B) "(BYTE *)&company_name" などを ctypes 呼び出しに変換する方法を教えてください。

ありがとうございました!

解決策: Zuljin のおかげで、次のことがわかりました。

import ctypes as ct

#<snip>

cid = ct.c_int()
cname = ct.create_string_buffer(256)
cavgincome = ct.c_float()
dtlib.dbbind(cdbconn, 1, INTBIND, 0, ct.byref(cid))
dtlib.dbbind(cdbconn, 2, NTBSTRINGBIND, 0, cname)
dtlib.dbbind(cdbconn, 3, REALBIND, 0, ct.byref(cavgincome))

while dtlib.dbnextrow(cdbconn) != NO_MORE_ROWS:
    print '%s | %s | %s' % (cid, cname.value, cavgincome)
4

1 に答える 1

3

これらの DBINT、DBCHAR、DBFLT8 タイプの背後にあるものを確認する必要があると思います。おそらくこれはint、char、およびdoubleです。そして、これらの基本的な型については、ctypes (おそらく c_int、c_char、c_double) を見つけることができます。したがって、関数によって返される値を保持する Python インスタンスを作成できるようになりました。これらの値をポインター パラメーターとして渡すには、byref()関数を使用する必要があります。このようなもの:

customer_id = c_int()
dbbind(dbconn, 1, INTBIND, 0, byref(customer_id))

編集:名前の場合、空の文字バッファーを作成する必要があります。そのために、ctypes は create_string_buffer と create_unicode_buffer の 2 つの関数を提供します。これらの関数からの出力オブジェクトは、関数に直接渡すことができます。これは、Windows での通常およびユニコードの scanf 関数呼び出しの例 (Python 3) です。

from ctypes import *
libc = cdll.msvcrt

buf = create_string_buffer(256) 
buf_u = create_unicode_buffer(256)

libc.scanf(b"%s",  buf)
libc.wscanf("%s",  buf_u)

print(buf.value)
print(buf_u.value)
于 2011-04-10T09:40:35.883 に答える