Odoo 中文社区

    • 注册
    • 登录
    • 搜索
    • 版块
    • 标签
    • 热门
    • 用户
    • 群组

    Odoo中文社区可以通过以下两个域名访问:shine-it.net , odoo.net.cn

    由于系统升迁的原因,本论坛部分较早期的内容存在格式和链接损坏失效的问题,并非本论坛系统本身的缺陷,望谅解

    本社区没有维护任何QQ群讨论组,任何与本社区同名的QQ群讨论组的言论与本社区无关!

    开发人员可以登录gitter讨论组: http://gitter.im/odoo-china/Talk, 需要github账号

    如果您登录系统碰到问题,请在微信公众号留言:

    Python开发调用DLL之ctypes初体验

    Python 开发
    3
    4
    13580
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • M
      mihi 最后由 编辑

      在开发过程中不可避免涉及到与系统动态链接库的交互,在python如果需要实现调用系统动态链接库函数,必须使用ctypes模块。ctypes使用相对简单。
      首先是dll的加载,windows下使用windll.LoadLibrary()函数。
      第二是方法的调用,也很简单,可以直接 "对象.原方法名()”就可以了。如:

      <br />&nbsp; &nbsp; &nbsp; &nbsp; self.carddll = windll.LoadLibrary(&quot;dcrf32.dll&quot;)<br />&nbsp; &nbsp; &nbsp; &nbsp; self.icdev = self.carddll.dc_init(100,0)<br />
      


      这里的dc_init()就是原来dll里的方法。
      第三数据类型的转换,这是最复杂的,可以分为4种情况。
      1.简单型(数值、字符、布尔)可以直接传递,不需要变化,比如上面的100,0 及其返回值icdev。
      2.简单类型的指针。也较简单。分别有两种实现方法。
      i.通过byref(参数)
      ii.通过Pointer方法来构造一个指针变量如

      <br />&nbsp; &nbsp; &nbsp; &nbsp; tempid = c_ulong(0)<br />&nbsp; &nbsp; &nbsp; &nbsp; ptempid = pointer(tempid)<br />&nbsp; &nbsp; &nbsp; &nbsp; st2 = self.carddll.dc_card(self.icdev, ModeALL, ptempid)<br />
      



      <br />&nbsp; &nbsp; &nbsp; &nbsp; tempid = c_ulong(0)<br />&nbsp; &nbsp; &nbsp; &nbsp; st2 = self.carddll.dc_card(self.icdev, ModeALL, byref(tempid))<br />
      


      以上两段代码等价
      3.字符串,在dll中往往是char *类型。这里又分为两种情况.
      i.如果传递方向是in很简单,直接把python中的字符串传入就可以了。
      ii.如果是传递方向是out较复杂,需要构造一个字符串buffer,如:

      <br />readdata1 = create_string_buffer(16)<br />st3 = self.carddll.dc_read(self.icdev, Block8, readdata1)<br />readdata = readdata1.value[0:12]<br />
      


      其中 readdata1就是读出的字符缓冲区,readdata是python字符串
      4.结构体,较复杂需要用ctypes重性定义特殊格式的类。(本次开发没有涉及,就不深入了)
      以下是完整的代码,通过threading.Thread类来实现多线程,通过多线程完成对射频的读取:

      <br />from&nbsp; ctypes import *<br />class DevWork(threading.Thread):<br />&nbsp; &nbsp; &quot;多线程实现读卡&quot;<br />&nbsp; &nbsp; def __init__(self,window):<br />&nbsp; &nbsp; &nbsp; &nbsp; threading.Thread.__init__(self)<br />&nbsp; &nbsp; &nbsp; &nbsp; self.window = window<br />&nbsp; &nbsp; &nbsp; &nbsp; self._terminate=False<br />&nbsp; &nbsp; &nbsp; &nbsp; #self.__suspend_lock = threading.Lock()<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; def terminate(self):<br />&nbsp; &nbsp; &nbsp; &nbsp; self._terminate = True<br />&nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; def OpenDev(self):<br />&nbsp; &nbsp; &nbsp; &nbsp; self.carddll = windll.LoadLibrary(&quot;dcrf32.dll&quot;)<br />&nbsp; &nbsp; &nbsp; &nbsp; self.icdev = self.carddll.dc_init(100,0)<br />&nbsp; &nbsp; &nbsp; &nbsp; if self.icdev &lt;= 0 :<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return -1<br />&nbsp; &nbsp; &nbsp; &nbsp; st = self.carddll.dc_load_key_hex(self.icdev,KEYSET0,Sec2,passwordA)<br />&nbsp; &nbsp; &nbsp; &nbsp; if st != 0 :<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.carddll.dc_exit(self.icdev)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return -2<br />&nbsp; &nbsp; &nbsp; &nbsp; return 1<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; def run(self):<br />&nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; tempid = c_ulong(0)<br />&nbsp; &nbsp; &nbsp; &nbsp; ptempid = pointer(tempid)<br />&nbsp; &nbsp; &nbsp; &nbsp; readdata1 = create_string_buffer(16)<br />&nbsp; &nbsp; &nbsp; &nbsp; olddata = &quot;a&quot; * 12<br />&nbsp; &nbsp; &nbsp; &nbsp; while True:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.sleep(3)&nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if self._terminate:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; st2 = self.carddll.dc_card(self.icdev, ModeALL, ptempid)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; st2 = self.carddll.dc_authentication(self.icdev, KEYSET0, Sec2)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; st3 = self.carddll.dc_read(self.icdev, Block8, readdata1)<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; readdata = readdata1.value[0:12]<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if olddata == readdata:&nbsp;  #同一张卡,不再操作<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.window.Input(readdata)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.sleep(1)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; olddata = readdata<br /><br />
      


      其中terminate()用来实现结束线程
      OpenDev()用来打开设备
      run()里边有个大循环,用来实现连续读取卡片内容。

         



      1 条回复 最后回复 回复 引用 0
      • mrshelly
        mrshelly 最后由 编辑

        赞赞赞......

        1 条回复 最后回复 回复 引用 0
        • D
          demo 最后由 编辑

          python可以用来操作单片机吗

          1 条回复 最后回复 回复 引用 0
          • First post
            Last post