C++/Qt 小知识记录5

工作中遇到的一些小问题,总结的小知识记录:C++/Qt

Windows下查看端口占用情况

如下为C++的调用实现

#include <Windows.h>
#include <WinSock.h>
#include <tcpmib.h>
#include <IPHlpApi.h>

#include <vector>
#include <memory>
#include <algorithm>
#include <iostream>
int CRetransferRequest::GetSupportPort(int nMin, int nMax)
{
	for (int i = nMin; i <= nMax; i++)
	{
		unsigned short usPort = (unsigned short)i;
		SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
		sockaddr_in addr;
		addr.sin_family = AF_INET;
		addr.sin_port = htons(usPort);
		addr.sin_addr.s_addr = htonl(INADDR_ANY);
		bind(s, (LPSOCKADDR)&addr, sizeof(addr));
		if (WSAGetLastError() == WSAEADDRINUSE)
		{
			//端口已被占用
			continue;
		}
		else
		{
			return i;
		}
	}

	return rand() % (nMax - nMin) + nMin;
}

同时在cmake中需要配置相关库依赖: ws2_32.lib、IPHlpApi.lib

# cmake下的依赖库
target_link_libraries(${PROJECT_NAME} 
    PRIVATE
	ws2_32.lib
	IPHlpApi.lib
)

C++调用Python三方库

以下是一些在做C++调用Python脚本时遇到的突出问题,或者必要的记录。(如何实现就不详细解说了,网上的教程很完备)

测试库有没有被加上的测试方法

// Try to import
PyObject* pName = PyUnicode_DecodeFSDefault(strModuleName.data());
PyObject* pModule = PyImport_Import(pName);

if (pModule != NULL) {
	// module exists
	printf("%s library is available.\n", strModuleName.data());

	// Clean up
	Py_DECREF(pModule);
}
else {
	// ImportError occurred
	PyErr_Print();
	fprintf(stderr, "Failed to import %s library.\n", strModuleName.data());
}

初始化使用Python的env环境,用Py_SetPythonHome设置

Py_SetPythonHome(L"../algorithm_py_env");

Py_Initialize();
if (!Py_IsInitialized())
{
	return -1;
}

GDAL相关的,需要把osgeo、rasterio的路径加入到运行环境变量

(假设Python环境在algorithm_py_env目录下)

PyRun_SimpleString("import os");
PyRun_SimpleString("os.environ['PATH'] = '../algorithm_py_env/Lib/site-packages/osgeo;../algorithm_py_env/Lib/site-packages/rasterio;'+os.environ['PATH']");
PyRun_SimpleString("os.environ['PYTHONPATH'] = '../algorithm_py_env/Lib/site-packages/osgeo;../Bin/algorithm_py_env/Lib/site-packages/rasterio;'+os.environ['PATH']");

如果调用的三方py模块,底层使用了C 扩展模块,如:rasterio,需要将ffi.dll系列库放入C++执行目录下,才能import成功。
是否需要显式处理 ffi.dll 取决于库的实现和其对底层资源的依赖
(并非所有的第三方库都需要直接使用 ffi.dll。使用 ffi.dll 主要是在构建和编写自定义的 C 扩展模块时,或者在 Python 中调用外部的 C 函数时才会涉及到。
许多第三方库通常是使用纯 Python 编写的,而不依赖于底层的 C 扩展。这些库在其实现中可能没有直接使用到 ffi.dll 或者其作用是被封装在库内部,因此用户在使用这些库时无需显式地处理 ffi.dll。)

  • C++执行目录需要放入的python相关动态库:
    在这里插入图片描述
  • 有依赖于C模块的py库,加入如下库(conda目录下可以找到):
    在这里插入图片描述

如果有Qt环境,编译的时候会报错到这个地方,是和Qt的slots宏冲突了

在这里插入图片描述

方法1. 把Python.h头文件放在最上面;

方法2. 改python的include/object.h内源码:

  • 把slots宏undef后再define:
  • #undef slots
  • PyType_Slot *slots;
  • #define slots Q_SLOTS

C++动态加载Python执行脚本

如果希望动态执行Python脚本,即每次(或者第二次以及之后)执行PyImport_ImportModule后,执行PyImport_ReloadModule来更新模块的加载。

	PyObject* pModule = NULL;
	PyObject* pFunc = NULL;
	PyObject* pArgs = NULL;
	PyObject* pRet = NULL;
	
	pArgs = argsFunc();
	
	std::stringstream ss;
	do
	{
	        pModule = PyImport_ImportModule(strModule.data());
	        if (pModule == NULL) {
	                ss << strModule << " module not found" << std::endl;
	                break;
	        }
	
	        if (m_bUseReload)
	        {
	                PyImport_ReloadModule(pModule); // 重新加载模块
	        }
	
	        pFunc = PyObject_GetAttrString(pModule, strFunc.data());
	        if (pFunc == NULL) {
	                ss << strFunc << " function not found" << std::endl;
	                break;
	        }
	
	        pRet = PyObject_CallObject(pFunc, pArgs);
	        if (pRet)
	        {
	                retFunc(pRet);
	        }
	
	} while (0);
	
	//释放内存
	if (NULL != pModule) Py_DECREF(pModule);
	if (NULL != pFunc) Py_DECREF(pFunc);
	if (NULL != pArgs) Py_DECREF(pArgs);
	if (NULL != pRet) Py_DECREF(pRet);
	
	return ss.str();

调试Python运行的小问题

[16676:0326/204323.820:ERROR:cache_util_win.cc(20)] Unable to move the cache: 拒绝访问。 (0x5)
[16676:0326/204323.820:ERROR:disk_cache.cc(205)] Unable to create cache
在windows下直接执行py文件可能报错,要用 python xxx.py 明确是用python执行

VS2022设置cpp和h的切换快捷建:Alt+o设置

个人习惯,所以特意改了
在这里插入图片描述

相关推荐

  1. YOLOv5-知识记录(二)

    2024-04-20 17:16:03       46 阅读
  2. 5G基础知识记录

    2024-04-20 17:16:03       32 阅读
  3. uni-app知识记录

    2024-04-20 17:16:03       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-20 17:16:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-20 17:16:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-20 17:16:03       87 阅读
  4. Python语言-面向对象

    2024-04-20 17:16:03       96 阅读

热门阅读

  1. coco128数据对象类别中英文对照json格式

    2024-04-20 17:16:03       38 阅读
  2. electron+Vue3构建桌面应用之IPC通讯

    2024-04-20 17:16:03       37 阅读
  3. 构建spotify的electron版本

    2024-04-20 17:16:03       38 阅读
  4. NLP预训练模型

    2024-04-20 17:16:03       31 阅读
  5. 微服务架构中的业务数据可视化设计

    2024-04-20 17:16:03       45 阅读
  6. Linux学习 - 常用和不太常用的实用awk命令

    2024-04-20 17:16:03       36 阅读
  7. go服务k8s容器化之grpc负载均衡

    2024-04-20 17:16:03       32 阅读