| 本想将写好的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。
 
 自己用VS2019建立下个DOS,空的工程,复制代码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
新建一文件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库   
 
 
 
 
 |