.py文件转成.dll文件的尝试1

.py文件转成.dll文件的尝试1,第1张

.py文件转成.dll文件的尝试1  1. 首先在csdn上搜索相关方法

结果诸如此类,好巧不巧都是那个简单的相加的函数,没有import的库,也没有复杂的return。于是本着先易后难的原则开始先学这个简单函数的转换。

按照他说的,打开我的pycharm,点击File-New Project  创建新项目并命名为pythonProject9,使用原有环境Sl(已安装cython),新建.py文件按照教程命名为run,内输入代码:

def str_add(str1, str2):
    return int(str1) + int(str2)

然后下一步就,需要新建一个run.pyx文件,并且有着奇怪的语法(应该是Cython语法?)总之没有任何解释就对了:(PS:我建立.pyx文件的方法是使用记事本)

cdef public int str_add(const char* str1,const char* str2):
  return int(str1) + int(str2)

两个函数相比之下只有第一行不同,也许以后扩展使用的时候也可以只改第一行定义行?有待日后的尝试。

接着按照教程在终端(当时以为是pycharm终端)输入

cython run.pyx

没有按照预期生成.c和.h文件,于是思考之后使用cmd运行上述代码,生成成功.

生成成功以后需要打开VS新建动态链接库项目,创建项目并起名为DLLrun

建立以后首先把配置和平台调整为release和x64如图:


 

 然后修改vc++包含目录为虚拟环境Sl中的include,修改库目录为Sl中的libs:

 再修改c++常规中的附加包含目录为Sl中的include:

 最后修改连接器输入中的附加依赖项为python38.libs(release对应pythonxx.lib,debug对应pythonxx_d.lib)其中数字根据自己实际环境而定.

 环境配置完成后,根据教程我们下一步建立一个c++文件,名为dllmain,可以看到当你新建一个dll工程,他会自动建立一个dllmain.cpp文件,但其中的代码是:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

而教程中的代码是:

#include 
#include 
#include "run.h"
extern "C"
{
    __declspec(dllexport) int __stdcall _str_add(const char * a, const char * b) //声明导出函数,类,对象等供外面使用
    {
        return str_add(a, b);
    }
}
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        Py_SetPath(L"D:/ProgramData/Anaconda3/envs/Sl/Lib"); //这个要根据自己电脑python安装的位置来
        Py_Initialize();
        //dll初始化的时候调用,这是python3的写法,python2改成,initrun()。参见生成的run.h
        //名称的命名规则为PyInit_+你的C文件的名称,此处也要注意修改
        PyInit_run();
        break;
    case DLL_PROCESS_DETACH:
        Py_Finalize();
        break;
    }
    return TRUE;
}

语法又有了一些变化但是文中依然没有任何的解释.也就是说这里扩展使用难以推进

接下来调整设置c/c++下预编译头选择不使用预编译头,高级选项下选择编译为c++代码.

全部配置完成后,点击生成-生成解决方案,出现报错如下:

打开说明LNK2001提示可能是lib配置缺少,把run.h和run.c添加到项目中以后再运行,可以运行但是运行之后会出现报错:

 

后来清除输出再次生成,终于成功生成DLL文件。:

测试dll文件是否可用:新建VS项目,添加Dllrun.dll到文件中,重新进行上述各种目录和库文件的设定,然后在主函数中输入代码:

#include 
#include 
#include 
using namespace std;
int main()
{
    typedef int(*pAdd)(const char* a, const char* b);
    // python_to_DLL.dll为你的dll名字,注意修改
    HINSTANCE hDLL = LoadLibrary(_T("Dllrun.dll"));
    cout << "hDLL:" << hDLL << endl;
    if (hDLL)
    {
        // 获取DLL中需要调用的函数的地址
        pAdd pFun = (pAdd)GetProcAddress(hDLL, "_str_add");
        cout << "pFun:" << pFun << endl;
        const char* stra = "12";
        const char* strb = "22";
        if (pFun)
        {
            int i = pFun(stra, strb);
            cout << "i = " << i << endl;
        }
    }
    // 调用dll测试
    //将字符变成int然后相加
    system("pause");
    return 0;
}

运行主程序,调用成功,结果如下图:

于是基础教程部分已经结束了,接下来靠自己弄更复杂的程序,目标是生成dll文件即可.

首先试一试包含库的文件如何转化

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5432730.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存