由于程序需要爬取一些网页上的数据并显示在Gui上,C/C++的库做爬虫不是很方便,因此需要Python做爬虫将结果返回到C/C++程序上。
安装cython
在已经安装python的机器上通过下述命令可以很方便的安装cython
pip install cython
将函数发布
有如下爬虫程序spider.pyx
from urllib import request
from urllib import error
from urllib import parse
cdef public int spider() except -1:
Request_URL = 'http://www.baidu.com'
response = request.urlopen(Request_URL, data, 0.1)
html = response.read().decode('utf-8')
print(html)
return 0
通过执行python setup.py build_ext --inplace
将上述文件编译为spider.h
和spider.c
,其中setup.py
如下
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("spider",["spider.pyx"])]
setup(
name = "spider.pyx",
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
编译动态链接库
- 在VisualStudio中创建空项目,在项目==》属性中将配置类型更改为动态库
- 在项目==》属性中配置VC++目录中的包含目录中添加一项
Python的安装路径\include
- 在项目==》属性中配置VC++目录中的库目录中添加一项
Python的安装路径\libs
- 在项目==》属性==》链接器==》输入中附加依赖项添加
python38.lib(PS.我的python版本为3.8,由安装版本而定)
- 将
spider.h
和spider.c
加入工作目录 - 创建main.cpp加入如下内容
#include <Python.h>
#include <Windows.h>
#include "spider.h"
extern "C"
{
__declspec(dllexport) int __stdcall _spider(void)
{
return spider();
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
static wchar_t* program;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
program = Py_DecodeLocale("spider", NULL);
PyImport_AppendInittab("spider", PyInit_spider);
Py_SetProgramName(program);
Py_Initialize();
PyImport_ImportModule("spider");
break;
case DLL_PROCESS_DETACH:
PyMem_RawFree(program);
Py_Finalize();
break;
}
return TRUE;
}
7.生成相应的dll,lib
调用API
调用的方式有两种(隐式调用和显式调用)
隐式调用(这种方式需要配置lib与上一过程的4类似
)
#ifdef __cplusplus
extern "C"
{
#endif
extern int _spider(void);
#ifdef __cplusplus
}
#endif
int main()
{
_spider();
return 0;
}
显示调用(无需配置lib,有dll即可使用)
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
// 调用dll测试
typedef int (*_spider)(void);
HINSTANCE hDLL = LoadLibrary(("spider.dll"));
cout << "hDLL:" << hDLL << endl;
if (hDLL)
{
// 获取DLL中需要调用的函数的地址
_spider _spiderFun = (_spider)GetProcAddress(hDLL, "_spider");
cout << "_spiderFun:" << _spiderFun<< endl;
if (_spiderFun)
{
cout << "ret = " << _spiderFun() << endl;
}
}
system("pause");
return 0;
}
References
[1] https://cython.org
[2] 手把手教你将Python程序打包为DLL
该demo可以在https://github.com/UWVG/spider获取Releases