结果诸如此类,好巧不巧都是那个简单的相加的函数,没有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文件即可.
首先试一试包含库的文件如何转化
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)