由源码生成Python可调用的dll

1. 不带参数的函数与调用

1.1. 创建项目

  • 首先创建一个c语言或者C++项目
  • 运行出来hello world
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oGHEycon-1686290398095)(null)]

1.2. 修改源码

  • 创建一个myDLL类
    动态链接库导出的类需要加关键字__declspec(dllexport),表示该函数将要被导出,否则无法生成lib文件。
    创建一个头文件和一个源文件
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MzcIXNrb-1686290398108)(null)]
  • myDLL.h
class Mymath {
	static void print_hello();
};

  • myDLL.cpp
#define DLLEXPORT extern "C" __declspec(dllexport)

#include "myDLL.h"
#include <iostream>

//打印hello world
DLLEXPORT void print_hello() {
	std::cout << "Hello World!" << std::endl;
}

1.3. 编译

  • 之后修改生成类型,改为dll
    项目属性-常规-配置类型-动态库,将其改为dll
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9lkZghWw-1686290398164)(null)]
  • 之后再次进行生成
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DGVCpVeL-1686290398151)(null)]
  • 可以看到现在在release文件夹中已经是生成了dll文件
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fSvi8byp-1686290398069)(null)]
  • 这个dll就是64位的dll,可以用于后续的其他程序的调用

1.4. 调用

  • 我们使用Python来进行调用
from ctypes import *
lib = CDLL("Project8.dll")
result = lib.print_hello()

可以看到,这样已经是正常调用了

hello world 的完整项目

2. 带参数的函数编译和调用

2.1. 新建.h头文件

pycall.h

### //test.h
#pragma once
class Mymath {
	int sum(int, int);
	int sub(int, int);
};
#pragma once

2.2. 新建cpp文件

pycall.cpp

### #define DLLEXPORT extern "C" __declspec(dllexport)
#include"pycall.h"
//两数相加
DLLEXPORT int  sum(int a, int b) {
	return a + b;
}
//两数相减
DLLEXPORT int sub(int a, int b) {
	return a - b;
}

2.3. 编译

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rIYOSULi-1686290398190)(null)]

2.4. 调用

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8VPmX5yQ-1686290398082)(null)]

3. 报错

  • AttributeError: function ‘printHelloWorld’ not found

  • 要调用的这个dll文件里面没有这个函数

  • 应该是在.cpp文件中定义函数的时候没有在之前添加DLLEXPORT用来声明供外部调用,所以生成的dll文件中没有这个函数,因此会出错
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-llhpeK49-1686290398137)(null)]

  • OSError: [WinError 126] 找不到指定的模块。

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eRTB3MQ2-1686290398177)(null)]

  • 出现找不到指定模块的问题通常是程序要加载某个DLL文件,但是这个DLL文件不存在就报错了。

  • 可以在PyCharm中打一个断点,看到底是缺哪个dll文件

  • dll文件的位数不匹配
    如果dll是32位,而自己的Python是64位的,那么肯定是无法正常用的

  • 尝试使用ctypes.windll.dx代替CDLL加载dx.dll

  • DLL依赖其他DLL
    如果dx.dll依赖其他DLL,而其他DLL没有被找到,也会产生此错误

匹配
如果dll是32位,而自己的Python是64位的,那么肯定是无法正常用的

  • 尝试使用ctypes.windll.dx代替CDLL加载dx.dll

  • DLL依赖其他DLL
    如果dx.dll依赖其他DLL,而其他DLL没有被找到,也会产生此错误

猜你喜欢

转载自blog.csdn.net/u014723479/article/details/131126189