zoukankan      html  css  js  c++  java
  • 使用Python调用动态库

    我个人在日常使用电脑时,经常需要使用Google,于是就要切换代理,基本上是一会儿切换为代理,一会儿切换成直连,老是打开internet 选项去设置,很不方便,于是我萌生了一个想法:

    做一个开关,我想用代理的时候,就点一下打开。不想用时,就再点一下关闭。

    简单的说,就是自动更改IE的代理设置。

    实际上这个功能可以使用纯python实现,其核心的原理就是使用 Windows API InternetSetOption。但是python去调用这个api相当复杂,不过人家已经实现过了,参见stackoverflow的问题

    不过话说回来,想调用windows api这件事,为什么不适用c/c++来实现呢,这对他们来说很简单就实现了,绕python一圈感觉不是很合理。

    所以,这一段用c++来写,然后其他地方要调用直接调用就好了,使用c++来更改代理服务器,代码大概长这个样子:

    IEPROXY_API bool setproxy(TCHAR* server, bool enabled)
    {
    	INTERNET_PER_CONN_OPTION_LIST list;
    	DWORD dwBufSize = sizeof(list);
    
    	// Fill the list structure.
    	list.dwSize = sizeof(list);
    
    	// NULL == LAN, otherwise connectoid name.
    	list.pszConnection = nullptr;
    
    	// Set three options.
    	list.dwOptionCount = 3;
    	list.pOptions = new INTERNET_PER_CONN_OPTION[3];
    
    	// Ensure that the memory was allocated.
    	if (nullptr == list.pOptions)
    	{
    		// Return FALSE if the memory wasn't allocated.
    		return false;
    	}
    
    	// Set flags.
    	list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
    	list.pOptions[0].Value.dwValue = enabled ? PROXY_TYPE_PROXY : PROXY_TYPE_DIRECT;
    
    	// Set proxy name.
    	list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
    
    	list.pOptions[1].Value.pszValue = server;
    
    	// Set proxy override.
    	list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
    	list.pOptions[2].Value.pszValue = TEXT("localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*");
    
    	// Set the options on the connection.
    	auto bReturn = InternetSetOption(nullptr,
    	                                 INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
    	if (bReturn)
    	{
    		InternetSetOption(nullptr,
    		                  INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
    		InternetSetOption(nullptr,
    		                  INTERNET_OPTION_REFRESH, nullptr, 0);
    	}
    
    	// Free the allocated memory.
    	delete[] list.pOptions;
    	return bReturn;
    }
    

    看起来代码有点长,其实有用的就那么两三行而已。

    总之,c++部分的代码做好,编译,最后生成一个dll,用dependency walker打开,里面能看到有三个c函数。

    dll内的函数
    下一步才是今天的主题,如果用python再调用。

    使用python调用

    尝试一下用ctypes来实现,ctypes提供跟c兼容的数据类型,也允许你调用DLL,你可以用ctypes来封装纯python的api。

    它使用起来也特别简单,基本上就只有三句话:

    1. from ctypes import *
    2. lib = cdll.LoadLibrary(dll_path)
    3. lib.setproxy(args.proxy, true)

    首先引入ctypes,这不必说了。然后使用cdll.LoadLibrary再装载dll,最后调用dll内部的函数,setproxy就是我之前写的c的函数,上面的图上有。整个过程很自然,很简单。

    我最先尝试的是用pyqt来做一个图形的界面,每次都在这个图形界面上打开和关闭代理,但后来觉得这也太复杂了,图形化的反而不如命令行简单直接,那不如直接写成命令行的算了,双击脚本a就打开,双击b就关闭,然后把a和b都放在桌面上就好了嘛。

    于是乎,就有了下面的两个bat文件:

    disable-proxy.bat

    python.exe .setproxy.py --proxy 127.0.0.1:8118 --switch 0

    enabled-proxy.bat

    python.exe .setproxy.py --proxy 127.0.0.1:8118 --switch 1

    我把这两个bat文件的快捷方式放在桌面上,用的时候双击其中一个就行。

    当然了,你都用c写成了一个dll了,那干脆你也写成一个独立的exe算了,exe内部解析命令行。
    是的,这样更好了,都不需要python的环境了,不过,下次再写吧。

    本文涉及到的源代码在 Github-Syler-Fun

    本文地址:https://1few.com/python-ctypes-call-c/

  • 相关阅读:
    [分享] Knockout.js 体验之旅
    [分享] 用NodeJs做一个小爬虫,附源码!
    [分享] 纯CSS完美实现垂直水平居中的6种方式
    [分享] 来,做一个问卷调查(有抽奖!)
    除非你是BAT,前端开发中最好少造轮子
    [分享] 微信支付中商户对个人用户付款案例
    30分钟做一个二维码名片应用,有源码!
    【分享】WeX5的正确打开方式(7)——数据组件详解
    基于phonegap,html5,ratchet,handlebars等技术的微表情APP
    html5实现web app摇一摇换歌
  • 原文地址:https://www.cnblogs.com/asis/p/7510292.html
Copyright © 2011-2022 走看看