c通过动态链接库调用python

由于程序需要爬取一些网页上的数据并显示在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.hspider.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
)

编译动态链接库

  1. 在VisualStudio中创建空项目,在项目==》属性中将配置类型更改为动态库
  2. 在项目==》属性中配置VC++目录中的包含目录中添加一项Python的安装路径\include
  3. 在项目==》属性中配置VC++目录中的库目录中添加一项Python的安装路径\libs
  4. 在项目==》属性==》链接器==》输入中附加依赖项添加python38.lib(PS.我的python版本为3.8,由安装版本而定)
  5. spider.hspider.c加入工作目录
  6. 创建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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值