我个人在日常使用电脑时,经常需要使用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函数。



下一步才是今天的主题,如果用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/

使用Python调用动态库的更多相关文章

  1. 一个简单的C共享库的创建及Python调用此库的方法

    /********************************************************************* * Author  : Samson * Date    ...

  2. Python调用C库

    Python调用C库 Python可以利用ctypes库很方便地调用C的库函数. C库例程: # file: a.c int sum(int a, int b){   int t = 0;   int ...

  3. # 2017-2018-2 20155228 《信息安全系统设计原理》 使用VirtualStudio2008创建和调用静态库和使用VirtualC++6.0创建和调用动态库

    使用virtual c++ 6.0创建和调用动态库 不得不说一下关于环境的问题 只要我打一个响指,一半的安装在win7上的VC6.0都会因为兼容性问题直接崩掉 懒得研究怎么解决兼容性的问题了,直接开一 ...

  4. [转]linux 调用动态库so文件

    记录一个面试被问到的问题. extern 有什么用途? 除了多文件共享全局变量外还有呢? extern "C" 的功能? 我想看完这篇文章就可以知道第三个问题了. 关于动态调用动态 ...

  5. windows 创建和调用 动态库,静态库

    windows创建和调用静态库 // MathFuncsLib.h namespace MathFuncs { class MyMathFuncs { public: // Returns a + b ...

  6. c++调用动态库失败解决办法

    c++调用动态库失败解决办法 之前写好的程序今天早上过来发现在服务器上出错了,于是就各种查问题,整整一个早上外加下午两个小时都在查这个问题,最终被我找到了问题: 在程序中我发现LoadLibrary( ...

  7. C++---初识《通过g++ / makefile 编译和调用动态库so文件》(ubuntu)

    C++---初识<通过g++ / makefile  编译和调用动态库so文件>(ubuntu) ------------------------目录------------------- ...

  8. LoadLibraryA 和 GetProcAddress 调用动态库

    通过LoadLibraryA 和 GetProcAddress,动态调用无需配置链接库lib和相关的头文件配置.下面介绍一个例子的实现 1.动态库 A.加法类 头文件:#pragma once cla ...

  9. Qt生成和调用动态库dll,和静态库.a(windows和linux通用)

    系统1:ThinkPad T570.Windows10.QT5.12.2(Qt Creater 4.8.2)一.动态库.dll的创建和调用1.在qtcreater中按如下步骤创建动态库,动态库名为my ...

随机推荐

  1. HDU 1251:统计难题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251 题意不难理解,就是先输入不知道多少个字符串,然后用一个空行结束这个输入,然后接下来不知道多少行再 ...

  2. poj2387 最短路

    题意:给出一堆双向路,求从N点到1点的最短路径,最裸的最短路径,建完边之后直接跑dij或者spfa就行 dij: #include<stdio.h> #include<string. ...

  3. hdu1224 dp(dp + 栈/父亲数组记录路径)

    题意:给定 n 个城市的有趣度,并给出可以从那些城市飞到那些城市.其中第一个城市即起始城市同样也作为终点城市,有趣度为 0,旅行途中只允许按有趣度从低到高旅行,问旅行的有趣度最大是多少,并输出旅行路径 ...

  4. CSS 属性用法备忘录

    ☆ margin: 0; padding: 0; :{ 顺时针 margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: ...

  5. $data[$i++]+=2;不等于$data[$i++]=$data[$i++]+2;

    $data=array(1,2,3,4); $i=1; $data[$i++]+=2; var_dump($data); echo $i; //输出:array(1,4,3,4) 和 2 $data= ...

  6. 【转】python mysql数据库 'latin-1' codec can't encode character错误问题解决

    UnicodeEncodeError: 'latin-1' codec can't encode character   "UnicodeEncodeError:'latin-1' code ...

  7. day20 python sys os time json pickl 正则

    字符组 : [字符组] 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示 字符分为很多类,比如数字.字母.标点等等. 假如你现在要求一个位置....9这10个数之一. 量词 几 ...

  8. log parser 微软iis 日志分析

    Log Parser 2.2 您可以从 Microsoft 下载中心下载 Log Parser. Log Parser 2.2 是一个功能强大的通用工具,它可对基于文本的数据(如日志文件.XML 文件 ...

  9. 【VB.NET】——若水归海

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/successA/article/details/34496209 看完台湾微软特约资深讲师的VB.N ...

  10. php脚本输出js代码不执行的解决办法和原理。

    <?phpecho "<script>alert('我弹出来了')</script>";?> 很简单你一句话就可以在PHP里面输出JS脚本让浏览 ...