grusirna的专栏

梳理那混乱的思绪

python

依赖

-) 操作系统

-) 操作系统的文件系统

本身

-) python解释器

-) python文件系统

项目一

实现功能

1.按键,将按键消息发送到其他窗口


功能分析

1.监视指定窗口按键

2.发送按键消息


实现思路

1.建包 ; 建立一个容器

2.建模块 ; 实现功能

3.# -*- coding: utf-8 -*-

4.依赖模块 ; ctypes

5.六种数据类型、函数、类、扩展

6.监视指定窗口按键; 需要一个C的DLL,DLL里执行python流程 ; python为面向对象,C为面向过程

  1).python中设置上钩子 ; SetWindowsHookExA(消息类型, dll的回调函数地址, dll句柄, 窗口线程)

  2).python中传递dll回调函数地址; 

  3)."dll"中准备回调函数

  4)."dll"的回调函数调用python功能

  5).python中准备功能

7.根据按键做发送消息的操作


项目问题总结

ctypes问题

1.当'调用'动态链接库的函数,加上()

2.当'传递'动态链接库的函数,去掉()

3.当'传递'python的函数给动态链接库,需转换;WINFUNCTYPE(python函数参数集合<逗号隔开>)(python函数名)

结构问题


附带:ctypes用法简介

一段示例:

from ctypes import *
user32 = windll.LoadLibrary('user32.dll')
user32.MessageBoxA(0,'ctypes is cool','Ctypes',0)


模块的思路

1.使用哪个函数

2.函数所在dll

3.调用约定

4.创建参数


使用ctypes的方法

1.加载动态链接库 ; 首先要做的是导入ctypes模块包,导入成功后调用ctypes为其提供的三个调用约定对象,三个对象为其封装好的dll对象可以直接调用,反之调用构造dll对象器

-) 三个对象: cdll(cdecl)、windll(stdcall)、oledll(stdcall)

-) 构造器: windll.LoadLibrary('dllName')

from ctypes import *
windll.user32.MessageBoxA(0,0,0,0)
#或者
windll.LoadLibrary('user32.dll').MessageBoxA(0,0,0,0)


2.调用动态链接库的函数 ,并简单使用python的数据类型传递; 主要是参数的处理

-) dll对象.函数()

-) python的字符串(Asic和Unicode)、整数、None可直接用于char*、wchar*、NULL类型

from ctypes import *
windll.LoadLibrary('user32.dll').MessageBoxW(None,None,u'hello',None)

3.构造简单的参数

-) ctypes提供了19种数据类型类,用于对应c的数据类型{c_bool:_Bool, c_char:char, c_wchar:wchar_t, c_byte:char, c_ubyte:unsigned char, c_short:short, c_ushort:unsigned short, c_int:int, c_uint:unsigned short, c_long:long, c_ulong:unsigned long, c_longlong:__int64 or long long, c_ulonglong:unsigned __int64 or unsigned long long, c_float:float, c_double:double, c_longdouble:long double, c_char_p:char*, c_wchar_p:wchar_t*, c_void_p:void*}

-) ctypes提供了申请缓冲区的函数: create_string_buffer(3),可用于动态修改,比如字符串


4.指名函数对象的参数类型 ; 指定格式可以防止不兼容的参数类型,并尝试转换为有效类型

printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
printf("String '%s', Int %d,Double%f\n","hi", 10, 2, 2.2)

5.创建C的结构体 ; 类名取之C结构的名,类继承自ctypes模块的Struct基类;只定义一个属性_fields_(一个2元组的列表类型)

class POINT(Structure):
    _fields_ = [('x', c_int), ('y', c_int)]
#以类名作为类型传递


6.处理回调函数 ; 首先定义python的函数对象,接着将函数对象转换为C的回调函数

#定义
def CallBack(code, wParam, lParam):
    pass
#调用工厂函数创建回调类(WINFUNCTYPE 或 CFUNCTYPE),注意最后一个参数是该回调函数的返回值
BACKCLASS = WINFUNCTYPE(c_int, c_int, c_int)
#用回调类创建一个C的回调函数
backObj = BACKCLASS(CallBack)
#将最终的对象传递给win API即可
windll.user32.SetWindowsHookExA(3,obj, None, threadId)


附带:minGW写dll

思路

1.建项目 ; 容器

2.建源文件

3.添加依赖 ; #include <windows.h>

4.编译器导出 ; extern "C" _declspec(dllexport)

5.写函数

6.生成dll ; g++/gcc -share test.cpp -o test.dll


附带:C++调用python

思路

1.建项目

2.建源文件

3.导入依赖;#include <python.h>

4.定义过程 ;

5.初始化解释器;  Py_Initialize();

6.单句运行python ; PyRun_SimpleString("python代码");

7.Python提供的对象 ; PyObject

8.转换过程的字符串为python对象 ; PyString_FromString("字符串")

9.导入脚本模块 ; PyImport_Import(python对象)



附带:gcc简单使用

1.GUN公社

2.GCC项目(GUN项目)

3.GCC for win32 -- mingw

4.GCC命令

-) 预编译过程; gcc -E test.c -o test.i ; 

-) 编译过程; gcc -S test.i -o test.s

-) 汇编过程; gcc -c test.s -o test.o

-) 连接过程; gcc test.o -o test

-) 四大过程合并;gcc -o test

-) 三大过程合并:gcc -c test.c(或 gcc -c test.c -o)

-) 四大过程合并且维护多个源文件:gcc -o test first.c second.c third.c



附带:一段C功能代码

LRESULT CALLBACK HookerCallBack(int nCode,WPARAM wParam, LPARAM lParam)
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	PMSG pMsg = (PMSG)lParam;
	if(pMsg->message == WM_KEYUP)
	{
		if(pMsg->wParam == VK_HOME)
		{
			if(theDlg == NULL)
			{
				hGameWnd = pMsg->hwnd;
				theDlg = new CWgDlg();
				theDlg->Create(IDD_DIALOG_WG);
				theDlg->ShowWindow(TRUE);
			}
			else
			{
				if(theDlg->IsWindowVisible())
					theDlg->ShowWindow(FALSE);
				else
					theDlg->ShowWindow(TRUE);
			}
		}
	}
	return CallNextHookEx(0,nCode,wParam,lParam);
}

void StartHook()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());//Afx =全局,Static = 静态,Module = 模块,State = 状态;
	HWND hGameWnd = FindWindow(NULL, ""); 
	if (hGameWnd == NULL) 
	{ 
		AfxMessageBox("未找到窗口");
		return;
	}
	DWORD dwThreadId=::GetWindowThreadProcessId(hGameWnd, NULL);
	::SetWindowsHookEx(WH_GETMESSAGE,HookerCallBack,::GetModuleHandle("fun.dll"),dwThreadId);
}


阅读更多
个人分类: python
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭