本想将写好的PYTHON文件打包成DLL供VS2019使用。
打包一下成众多文件,发再1个多GB,打包成独立exe文件也有400MB。
两行代码就这么大,看来也没啥意义再打包了。
python环境安装好了,就直接在本地用吧。
用vs2019直接调用python写好的py文件就好,也很方便。
这里记录下操作过程遇到的坑与解决方法。
也是第一次接触python,折腾的够呛。
首先也是自行安装VS2019,Anacoda3,pycharm.
我都是使用最新版本的64位。
可参考先前写的帖子。
https://www.gkbc8.com/forum.php?mod=viewthread&tid=15933
产生用pycharm或VS2019编写一个PY文件用于测试。
内容如下,涉及的第三方库都可以在Anacoda3里下载安装。
我这里是测试使用EASYOCR库。
主要是想通过VS2019直接调用下面的函数ocr。
- from gettext import gettext
- import easyocr
- # 结果为rect,文本,可信度 [([[189, 75], [469, 75], [469, 165], [189, 165]], '愚园路', 0.3754989504814148) ]
- # result = reader.readtext('d:/1.bmp') #
- # 结果为简单的字符数组,如['愚园路', '西', '东', '315', '309', 'Yuyuan Rd.', 'W', 'E'];
- # result = reader.readtext('d:/1.bmp', detail=0, paragraph=True)
- # file = open('C:/Users/baikhgmv/Desktop/' + 'new' + '.txt', 'w')
- # file.close()
- # print(result)
- # gettext(message=1)
- reader = easyocr.Reader(['ch_sim', 'en'], gpu=False) # 仅需初始化一次;
- def typeof(variate):
- variate_type = None
- if isinstance(variate, int):
- variate_type = "int"
- elif isinstance(variate, str):
- variate_type = "str"
- elif isinstance(variate, float):
- variate_type = "float"
- elif isinstance(variate, list):
- variate_type = "list"
- elif isinstance(variate, tuple):
- variate_type = "tuple"
- elif isinstance(variate, dict):
- variate_type = "dict"
- elif isinstance(variate, set):
- variate_type = "set"
- return variate_type
- def com(s):
- print(s)
- rst = '123'
- return rst
- def ocr(filepath):
- rst = reader.readtext(filepath, detail=0, paragraph=True)
- print(typeof(rst))
- print(rst)
- return rst
复制代码 自己用VS2019建立下个DOS,空的工程,
新建一文件test.cpp。复制下面的内容,再设置路径。
- #include "stdio.h"
- #include "stdlib.h"
- //#include "detect_text.h"
- //#pragma comment(lib,"OCRDLL.lib")
- #include <string>
- #include <Python.h>
- #include<iostream>
- #include<Windows.h>
- using namespace std;
- wchar_t* utf_8ToUnicode(const char* u8s)
- {
- int wcsLen = MultiByteToWideChar(CP_UTF8, NULL, u8s, (int)strlen(u8s), NULL, NULL)+1;
- wchar_t* wcString = new wchar_t[wcsLen];
- ZeroMemory(wcString, wcsLen);
- MultiByteToWideChar(CP_UTF8, NULL, u8s, (int)strlen(u8s), wcString, wcsLen);
- return wcString;
- }
- char* unicodeToAnsi(wchar_t* wcString)
- {
- int len = WideCharToMultiByte(CP_ACP, NULL, wcString, -1, NULL, NULL, NULL, NULL)+1;
- char* str = new char[len];
- ZeroMemory(str, len);
- WideCharToMultiByte(CP_ACP, NULL, wcString, -1, str, len, NULL, NULL);
- return str;
- }
- int main()
- {
- //<>初始化python模块
- Py_SetPythonHome(L"D:\\ProgramData\\Anaconda3\\envs\\easyocr");
- Py_Initialize();
- if (!Py_IsInitialized())
- {
- cout << "初始化失败" << endl;
- Py_Finalize();
- return 0;
- }
- PyRun_SimpleString("import sys");
- PyRun_SimpleString("sys.path.append('./')");//设置python模块搜寻位置,文件放在.cpp文件一起
- PyObject* pModule = NULL;
- PyObject* pFunc = NULL;
- PyObject* pArg = NULL;
- pModule = PyImport_ImportModule("ocr");//Python文件名
- if (!pModule)
- {
- cout << "py文件导入失败" << endl;
- }
- else
- {
- pFunc = PyObject_GetAttrString(pModule, "ocr");//Python文件中的函数名
- if (!pFunc)
- {
- cout << "函数导入失败" << endl;
- Py_Finalize();
- }
- PyObject* pyParams = Py_BuildValue("(s)", "D:\\1.bmp");//c++类型转python类型
- pArg = PyEval_CallObject(pFunc, pyParams);//调用函数
-
- if (PyList_Check(pArg))
- {
- PyObject* list_item = NULL;
- char* pStr = NULL;//c类型的列表元素
- for (int sb=0; sb < PyObject_Size(pArg); sb++)
- {
- //根据下标取出python列表中的元素,再转为字符串;
- list_item = PyList_GetItem(pArg, sb);
- PyArg_Parse(list_item, "s", &pStr);
-
- //python3默认为utf8编码,将其转为ansi,正常显示结果;
- wchar_t* p = NULL;
- char* p2 = NULL;
- p = utf_8ToUnicode(pStr);
- p2 = unicodeToAnsi(p);
- cout << p2 << "\r\n" << endl;
- //
- if (p)
- delete[]p;
- if (p2)
- delete[]p2;
- }
- }
- }
- char a = getchar();
- Py_Finalize();
- return 0;
- }
复制代码 路径我的设置是
头文件路径
D:\ProgramData\Anaconda3\envs\easyocr\include
库文件路径
D:\ProgramData\Anaconda3\envs\easyocr\libs
D:\ProgramData\Anaconda3为Anaconda3的安装位置,
我使用Anaconda3创建了一个新的环境easyocr,
所以使用此环境下的路径。
直接编译工程,正常生成exe程序。
将刚才的py文件复制一份到exe程序与test.cpp都一份。
一个是编译时会用到,一个是运行时会用到。
直接进行程序。
不出意外,会有如下提示错误。
mkl-service第三方库我在Anaconda3创建的环境easyocr里,是有安装的,
版本也是匹配的,最后大量查阅网络,是路径问题。
- D:\ProgramData\Anaconda3\envs\easyocr\lib\site-packages\numpy\__init__.py:138: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service
- from . import _distributor_init
- py文件导入失败
复制代码
解决方法如下。
电脑系统环境变量Path添加python环境的三个路径。
如我的
系统环境设置,重启电脑
D:\ProgramData\Anaconda3\envs\easyocr
D:\ProgramData\Anaconda3\envs\easyocr\Scripts
D:\ProgramData\Anaconda3\envs\easyocr\Library\bin
测试后,反复测试还是不行。
直接放弃,关机睡觉。
第二天继续开机测试,一切OK了。
经过反复测试,确定了原因。
系统环境设置后,重启电脑才能正常,重要的事搞三遍。
系统环境设置,重启电脑
系统环境设置,重启电脑
系统环境设置,重启电脑
真恶心。
最后
在C++调用python库前还得Py_SetPythonHome。
调用函数设置
Py_SetPythonHome(L"D:\\ProgramData\\Anaconda3\\envs\\easyocr");
或也通过添加系统环境变量PYTHONHOME == D:\\ProgramData\\Anaconda3\\envs\\easyocr。
我已放弃折腾,在本地能用就好,也不在乎如何搞更加简便。
等后期有时间了,系统熟悉python编程。
好在python用的人多,遇到 的问题一搜都有答案,就是折腾人。
一切编译OK,运行程序。
效果如下
VS2019通过C语言直接调用PYTHON库
|