ue和maya中py文件加密为pyd并调用
maya中py文件加密为pyd文件
这里先记录下踩坑过程~
踩坑记录
- 开始在pycharm中安装Cython和easycython(两者一样,转化结果都为pyd),注意转换pyd时如果提示没有微软的Visual C++ Build Tools 2015,下载一个安装就好,安装提示找不到包或损坏那就镜像安装
- 测试pyd文件,在pycharm中正常调用,但是在maya中调用报‘找不到模块’的错误。
然后网上找了可能的原因
- 第一种:Python import .pyd文件时会搜索sys.path列表中的路径
import之前用sys.path.append()方法加入xxx.pyd所在路径- 第二种:可能是xxx.pyd调用了其他的DLL文件,且其调用的DLL文件无法被搜索到。
问题详细与解决介绍- 但经过测试在maya中任然不能正常调用转化的pyd文件,然后突然想到是不是转换pyd时用的是python3的解释器进行转化的而maya2019用的是python2,然后就去官网下载了maya2019对应的python2.7,然后又使用python2.7重新生成pyd文件,然而maya依然调用不了。
成功实现
- 但我想到maya本身也有调用的pyd(maya 自身就集成了 PySide 的 pyd 模块),所以,只要接下来要找出怎么编译 maya 的 pyd 方法,或许 maya PySide 是用 C++ 来直接编写,然后编译成 pyd,不过 cythonize 已经把 py 生成了 c 或者 cpp,现在还不确定问题出在哪个阶段。
参考博文:https://www.cnblogs.com/ibingshan/p/10346354.html - 这跟编译 mayapy.exe 的 msc 有很大关系,运行 mayapy.exe 就能获取 python 的版本 和 msc 的版本
如何查看不同版本的maya中使用的python是什么版本:
- 对桌面maya的快捷图标直接右键->打开文件所在的位置
- 在打开的文件夹中找到mayapy.exe,双击打开,就能看见python版本了
至于 msc 和 VS 的版本对应:
注意:镜像安装安装Visual Studio 2015时提示找不到包或损坏那就先到下载的镜像包中,手动先安装提示的包,安装成功后再在Visual Studio 2015点击跳过包。 - 对桌面maya的快捷图标直接右键->打开文件所在的位置
- 接下来就是编译Cython的源码了。
参考博文:https://www.cnblogs.com/ibingshan/p/10346354.html - 最后就是编译pyd文件
编译pyd遇到坑,可以参考:https://www.cnblogs.com/ibingshan/p/10334471.html
py文件转pyd文件
在要转换的py文件同级目录下新建build.py文件,该文件作用是编译当前脚本路径下的 test_pyd.py | 输出 test_pyd.pyd 文件(test_pyd.py与build.py在同一级目录)1
2
3
4
5
6from distutils.core import setup
from Cython.Build import cythonize
setup(
#name = 'xxx',
ext_modules = cythonize("menu_exporter.py")
)上面就是 build.py 脚本写的代码,test_pyd 的代码就是简单的
print("hello world")
然后在cmd中cd到需要转化的py文件所在的目录,执行”C:\Program Files\Autodesk\Maya2019\bin\mayapy.exe” build.py build
执行上面的命令就可以在当前路径下生成 build/lib.win-amd64-2.7/test_pyd.pyd 的文件
在 maya 导入 test_pyd.py 可以打印出 hello world
UE中py文件加密为pyd文件
同样这里先记录下踩坑过程~
踩坑记录
- 刚开始直接在原有的pycharm(此时python版本为3.9)中安装cython和easycython库,但是这时候生成pyd会出现错误(mspdb140.dll这个错误)
- 成功编译pyd后在UE中不能正常调用
成功实现
直到看到了一篇博客,将python文件,加密成UE4可用的pyd文件:https://blog.csdn.net/weixin_43912248/article/details/122424873
注意:pyd本身的问题
ue的py插件转为pyd后能够成功调用了,但是部分功能没有实现,开始以为是try(抛出异常)的原因,于是就换成了contextlib 库的 suppress方法进行抛出异常,但是部分功能任然不能正常运行,于是我去掉了try(抛出异常)部分的函数,再转换为pyd运行时报了某个函数运行时没有参数传入。
经过多番周折,查看pyd的官方文档后,发现了问题,也就是没有封装在class外的def方法,只能一个类进行调用,不能多个类进行调用。于是我将这个需要多个类调用的方法封装进每个类中,然后转换为pyd后再次运行,所有功能正常。(这里还是用的是try进行抛出异常,而且是能够正常抛出异常的)