Python /Cython/C/C++ dll 制作过程教程课
落霞归雁-思维框架
2022年03月28日 01:24

Cython dll 制作过程

1、安装python3.6.6  win32 的

制作 win32 位的dll 需要python 为32为的

安装python 注意一定要勾选 ,后两项。

2、先安装 pip install cython    默认安装版本就可以

不建议指定版本 cython 的版本

https://www.lfd.uci.edu/~gohlke/pythonlibs/#cython

cython

显示以下信息说明安装成功

Successfully installed cython

3、先创建一个py文件

def getCross(str1, str2):

return int(str1) + int(str2)

已制作完成的文件参照附件

编辑以下代码  命名为run.pyx文件 【pxy 也是可以的】

4、把py代码改为cython代码

#cython: language_level=3

cdef public getCross(const int str1,const int str2):

return str1+str2

5、文件所在目录 执行 cython run.pxy

生成.c和.h文件

6、安装VS2022 社区版 选中 C++  我安装的时候没截图。安装过程不在这里单独说

在得到了.c和.h文件后,我们需要为其创建一个VS DLL工程。打开VS软件,新建win32项目,其中应用程序类型选择DLL,附加选项选择空项目。

https://blog.csdn.net/qq78442761/article/details/107653293

我用的是VS2020  ,如下图操作。文件-新建-项目

 

 

确认后,弹出以窗口,准备工作做好。

然后最后一步配置以下编译环境,否则不识别Python.h 头文件。

 

库目录选择 ,python 32 位 的 libs 目录,我的是C:\python_32\libs

编译环境设置为 设置为 Debug  平台设置为Win32  。导入

7、写代码前一定要认真配置以上环境。

将刚刚的.c和.h文件==复制到项目==存放代码的文件夹并添加到项目中。在项目中添加一个空的dllmain.cpp并添加如

下代码:  源代码-添加 - 新建项

#include <Python.h>

#include <Windows.h>

#include &#​34;run.h"

#define DLLEXPORT extern &#​34;C" __declspec(dllexport)

DLLEXPORT int _getCross(int a, int b) {

return PyLong_AsLong(getCross(a, b));   //该句要换成 return PyLong_AsLong(getCross(a,b));

}

//return PyLong_AsLong(str_add(PyUnicode_FromString(a), PyUnicode_FromString(b)));

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {

switch (fdwReason) {

case DLL_PROCESS_ATTACH:

Py_Initialize();

PyInit_run();

break;

case DLL_PROCESS_DETACH:

Py_Finalize();

break;

}

return TRUE;

}

 

8、查看编译后的dll文件 并验证是否正确

项目

 

【1】第一种方式用python 调用该dll 方法

 

#-- coding: utf-8 --

import ctypes

dlls="test.dll&#​34;

Objdl= ctypes.cdll.LoadLibrary(dlls) #如果dll是stdcall调用,则python中用windll加载,如果dll是cdecl调用,则python用cdll加载

print(Objdl)

b=Objdl._getCross(1,22)

print(b)00000

 

【2】第二种方法、如果想用PB,powerbuild调用dll  ,则 需要对项目重新打包

修改为#//PB 为标准winapi即pasical 压栈顺序 需要stdcal。附件为制作std_dll  项目。请参考

不要漏掉 def文件

Source.def 文件

LIBRARY

EXPORTS

_getCross

 

1.在什么情况下需要使用.def的模块定义文件?

  使用_stdcall到处函数的时候需要使用.def的模块定义文件,使用__declspec(dllexport) 到处函数不需要使用.def文件。

2.定义的.def文件添加进工程后无效?

  此时还需要在 “属性->连接器->输入->模块定义文件 ” 的设置中,将模块定义文件添加进来,然后再重新编译即可。

改成Source

#include <Python.h>

#include <Windows.h>

#include &#​34;run.h"

#define DLLEXPORT extern &#​34;C" __declspec(dllexport)

DLLEXPORT int __stdcall _getCross(int a, int b) {

return PyLong_AsLong(getCross(a, b));   //该句要换成 return PyLong_AsLong(getCross(a,b));

}

//return PyLong_AsLong(str_add(PyUnicode_FromString(a), PyUnicode_FromString(b)));

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {

switch (fdwReason) {

case DLL_PROCESS_ATTACH:

Py_Initialize();

PyInit_run();

break;

case DLL_PROCESS_DETACH:

Py_Finalize();

break;

}

return TRUE;

}

######################################################################

返回字符串

return PyBytes_AsString(getCross(a, b));   //该句要换成 return PyLong_AsLong(getCross(a,b));

 

#####################################################################

PB 引入外部函数

Function   Int   _getCross()  LIBRARY "test.dll&#​34; Alias for "_getCross;Ansi&#​34;

事件调用:

int a

int b

a=111

b=222

try

st_3.text=  string( _getCross())

Catch(RunTimeError e)

MessageBox("异常&#​34;,e.getmessage());

st_3.text= "异常&#​34;

FINALLY

END TRY

 

PB调用 Cython 例子

结尾:

另外还有C语言 调用 cython dll

以及C语言制作DLL 后 python 调用 特殊说明

https://note.youdao.com/s/SbA5YVBr