• Ctypes简单应用以及PyQt5等简单使用过程中遇到的部分问题


    最近接到了个需求,需要在linux下做一个demo,对接公司自己的so,此so负责节点通讯等功能,前台的demo负责界面呈现。

    此软件为CS架构,上文提到的动态库,负责与服务器之间的通讯,对上层UI只提供初始化等基本接口,通过回调函数,利用字符串形式xml与UI进行交互。

    我所在的小组平时负责通讯平台部分,即节点通讯与基础数据管理(实体信息cache)等。

    之前做过一段时间的wpf,这次要做linux下的界面demo一开始有点没思路,查了下资料,QT是个不错的选择。

    说干就干,正好前阵子看了看python,所以这次开发选了PyQt5。

    确定的方案之后做了一下几件事:

      1.搭建环境(ubuntu16.04,python3.6,pycharm2017.3.3,PyQt5)

      2.寻找python调用so的解决方案(Ctypes)

      3.理解基本的QT编程(其实最后也没怎么看,pyUI 很简单生成py文件之后,直接继承下,直接就能实现界面与逻辑的分离,的确挺好用,不过UI的复杂设计没有看太多)

    总体下来还算顺利,排坑大概用了有效时间两天。

      主要遇到的问题:

      1.pycharm中引用PyQt5 提示 No moudle named ‘PyQt5’,但是在vsCode和命令行中正常,最终的发现是pyCharm的解释器环境问题,pyCharm会默认搭建venv把python环境复制出来一份,但是site-packages并不会复制,导致了却上相应扩展包

        解决:Setting->Project Interpreter (解释器)中选择 Add Local... (点击右上方解释器右侧的小齿轮),添加existing environment 把本机中已经安装的python路径输入 选择python.exe 即可。

      2.ctypes类库的使用

        主要是两个问题,1.结构体的传递  2.函数指针的传递。

        最终的解决:

    python

    import sys, os
    from ctypes import *
    
    CMPFUNC = CFUNCTYPE(None,c_wchar_p)#第一个参数为返回值,其余为参数列表 一开始这个地方没看懂,费了点时间才搞清楚
    
    def py_cmp_func_onResponse(Str):
        print(Str)
    
    class InitAPIData(Structure):
        _fields_ = [
            ("_responseback", CFUNCTYPE(None,c_wchar_p)),
            ("_strLocalLocalSipIP", c_wchar_p),
            ("_nlocalSipPort", c_int),
        ]
    initData = InitAPIData(CMPFUNC(py_cmp_func_onResponse),'strForTest',93424)
    
    
    libtest = cdll.LoadLibrary(d)
    libtest.test_a()
    libtest.test_b(byref(initData))
    print('end')
    

      

    测试so部分的测试文件:.h头文件

    #include <stdio.h>
    #ifdef __cplusplus
    extern "C"{
    
    
    typedef wchar_t WCHAR;
    
    typedef WCHAR TCHAR;
    
    
    typedef void(* OnResponse)(TCHAR*);
    
    
    typedef struct InitAPIData_t{
    	
    
    	OnResponse _responseback;//call back
    
    	TCHAR* _strLocalLocalSipIP;//local sip ip
    
    	int _nlocalSipPort;//local sip port
    
    }InitAPIData;
    
    
    void test_a();
    
    void test_b(InitAPIData *pdata);
    }
    #endif
    

      cpp文件

    #include "so_test.h"
    #include <iostream>
    
    using namespace std;
    
    void test_a(){
    
            printf("this is test_a ...
    ");
    
    }
    
    void test_b(InitAPIData *pdata){
    	
    	//std::string s1 = pdata->_strLocalLocalSipIP;
    	//std::cout << "str1 :"<<*(pdata->_strLocalLocalSipIP)<<std::endl;
    
    	const wchar_t * txt = pdata -> _strLocalLocalSipIP;
    	wstring ws(txt);
    
    	string str(ws.begin(), ws.end());
    	
    	std::cout <<"str: "<<str<<std::endl;
    	
    	const char* t1  = "1234";
    	pdata->_responseback((TCHAR*)txt);
    
    	std::cout <<"Port: "<<pdata -> _nlocalSipPort <<std::endl;	
    	
    	std::cout<<"pdata -> _nlocalSipPort: "<<pdata->_nlocalSipPort<<std::endl;
    	
    }
    

      附上官网参考文献地址:https://docs.python.org/2/library/ctypes.html

      3.其他   

        再就是qt部分看了下生成的UI文件,感觉总体上还是比较好理解的,界面与业务的分离也很好处理,特效方面没怎么看只是拖了几个控件,弄了下前后台的交互。另外重新开始看下linux 毕业之后看的不多,太多东西要学了,还得恶补下。对了,

      环境搭建方面建议除了pycharm全部pip 或者 apt-get  解决问题,很简便。

  • 相关阅读:
    【Leetcode_easy】852. Peak Index in a Mountain Array
    【Leetcode_easy】849. Maximize Distance to Closest Person
    【Leetcode_easy】844. Backspace String Compare
    【Leetcode_easy】840. Magic Squares In Grid
    【Leetcode_easy】836. Rectangle Overlap
    【Leetcode_easy】832. Flipping an Image
    【Leetcode_easy】830. Positions of Large Groups
    【Leetcode_easy】824. Goat Latin
    【Leetcode_easy】821. Shortest Distance to a Character
    【Leetcode_easy】819. Most Common Word
  • 原文地址:https://www.cnblogs.com/xiapuxiaohei/p/8399255.html
Copyright © 2020-2023  润新知