windows下python调用dll的方法
VS生成dll
关于VS生成dll文件供另一个C++程序调用的方法请参考我的这篇blog:
VS生成动态链接库dll的方法
可供python调用的dll生成
在生成dll时,函数对外提供接口标志由
__declspec(dllexport)
改为
extern "C" __declspec(dllexport)
完整声明示例:
extern "C" __declspec(dllexport) int add(int a,int b);
生成的dll文件就可以供python调用了。
因为python版本是64位的,因此生成dll时必须设置成x64,win32将会报错。
python调用dll方法
传入实数demo
C++生成dll代码:
#include "stdafx.h"
extern "C" __declspec(dllexport) int add1(int a, int b);
int add1(int a, int b)
{
return a + b;
}
将VS_create_dll.dll放在与python相同文件夹下。
python调用代码
import ctypes as C
dll = C.cdll.LoadLibrary('VS_create_dll.dll')
#1.传入实数调用demo
result1 = dll.add1(2,3)
print("传入实数调用demo:")
print(result1)
传入指针demo1
C++生成dll代码:
#include "stdafx.h"
extern "C" __declspec(dllexport) void add2(int a, int b, int *c);
void add2(int a, int b, int *c)
{
*c = a + b;
}
将VS_create_dll.dll放在与python相同文件夹下。
python调用代码
import ctypes as C
dll = C.cdll.LoadLibrary('VS_create_dll.dll')
#2. 传入指针调用demo1
result2 = C.c_int(0)#定义int类型变量,初始值为0
dll.add2(4, 5, C.byref(result2))#byref指明参数传递时为引用传递,对应C中的指针传递
print("传入指针调用demo1:")
print(result2.value)#.value可以查看变量的值
传入指针demo2
C++生成dll代码:
#include "stdafx.h"
extern "C" __declspec(dllexport) void add3(int *a, int *b, int *c);
void add3(int *a, int *b, int *c)
{
*c = *a + *b;
}
将VS_create_dll.dll放在与python相同文件夹下。
python调用代码
import ctypes as C
dll = C.cdll.LoadLibrary('VS_create_dll.dll')
#3.1 传入指针调用demo2 方法一
a = C.c_int(6)
b = C.c_int(7)
result3_1 = C.c_int(0)
dll.add3(C.byref(a), C.byref(b), C.byref(result3_1))
print("传入指针调用demo2 方法一:")
print(result3_1.value)
#3.2 传入指针调用demo2 方法二
result3_2 = C.c_int(0)
add3 = dll.add3
add3.argtypes = [C.POINTER(C.c_int),C.POINTER(C.c_int),C.POINTER(C.c_int)]
add3(a,b,result3_2)
print("传入指针调用demo2 方法二:")
print(result3_2.value)
传入字符串demo
C++生成dll代码:
#include <iostream>
extern "C" __declspec(dllexport) int get_str_length(char *str);
int get_str_length(char *in_str)
{
std::string str(in_str);
return str.length();
}
将VS_create_dll.dll放在与python相同文件夹下。
python调用代码
import ctypes as C
dll = C.cdll.LoadLibrary('VS_create_dll.dll')
#4.1 传入字符串调用demo 方法一
p_str = C.c_char_p(b'hello')#或p_str = b'hello'
str_length1 = dll.get_str_length(p_str)
print("传入字符串调用demo 方法一:")
print (str_length1)
#4.1 传入字符串调用demo 方法二
get_str_length = dll.get_str_length
get_str_length.argtypes = [C.c_char_p]
get_str_length.restype = C.c_int
str_length2 = get_str_length(p_str)
print("传入字符串调用demo 方法二:")
print (str_length2)
传入字符串指针并返回字符串demo
C++生成dll代码:
#include <iostream>
#pragma warning(disable : 4996)
extern "C" __declspec(dllexport) char* get_string(char *in_str);
char* get_string(char *in_str)
{
strcpy(in_str, "I am str_in");
char *out_str = "I am str_out";
return out_str;
}
将VS_create_dll.dll放在与python相同文件夹下。
python调用代码
import ctypes as C
dll = C.cdll.LoadLibrary('VS_create_dll.dll')
# 传入空字符串指针,返回字符串demo
get_string = dll.get_string
get_string.argtypes = [C.c_char_p]
get_string.restype = C.c_char_p
in_str = C.create_string_buffer(1024,'\0')
out_str = get_string(in_str)
print("传入空字符串指针,返回字符串demo:")
print(in_str.value)
print(out_str)
完整代码
C++生成dll代码:
#include <iostream>
#pragma warning(disable : 4996)
extern "C" __declspec(dllexport) int add1(int a, int b);
extern "C" __declspec(dllexport) void add2(int a, int b, int *c);
extern "C" __declspec(dllexport) void add3(int *a, int *b, int *c);
extern "C" __declspec(dllexport) int get_str_length(char *str);
extern "C" __declspec(dllexport) char* get_string(char *in_str);
int add1(int a, int b)
{
return a + b;
}
void add2(int a, int b, int *c)
{
*c = a + b;
}
void add3(int *a, int *b, int *c)
{
*c = *a + *b;
}
int get_str_length(char *in_str)
{
std::string str(in_str);
return str.length();
}
char* get_string(char *in_str)
{
strcpy(in_str, "I am str_in");
char *out_str = "I am str_out";
return out_str;
}
将VS_create_dll.dll放在与python相同文件夹下。
python调用代码
import ctypes as C
dll = C.cdll.LoadLibrary('VS_create_dll.dll')
#1.传入实数调用demo
result1 = dll.add1(2,3)
print("传入实数调用demo:")
print(result1)
#2. 传入指针调用demo1
result2 = C.c_int(0)#定义int类型变量,初始值为0
dll.add2(4, 5, C.byref(result2))#byref指明参数传递时为引用传递,对应C中的指针传递
print("传入指针调用demo1:")
print(result2.value)#.value可以查看变量的值
#3.1 传入指针调用demo2 方法一
a = C.c_int(6)
b = C.c_int(7)
result3_1 = C.c_int(0)
dll.add3(C.byref(a), C.byref(b), C.byref(result3_1))
print("传入指针调用demo2 方法一:")
print(result3_1.value)
#3.2 传入指针调用demo2 方法二
result3_2 = C.c_int(0)
add3 = dll.add3
add3.argtypes = [C.POINTER(C.c_int),C.POINTER(C.c_int),C.POINTER(C.c_int)]#指明参数类型和数量
add3(a,b,result3_2)
print("传入指针调用demo2 方法二:")
print(result3_2.value)
#4.1 传入字符串调用demo 方法一
p_str = C.c_char_p(b'hello')#或p_str = b'hello'
str_length1 = dll.get_str_length(p_str)
print("传入字符串调用demo 方法一:")
print (str_length1)
#4.1 传入字符串调用demo 方法二
get_str_length = dll.get_str_length
get_str_length.argtypes = [C.c_char_p]#指明参数类型和数量
get_str_length.restype = C.c_int#指明返回类型
str_length2 = get_str_length(p_str)
print("传入字符串调用demo 方法二:")
print (str_length2)
# 传入空字符串指针,返回字符串demo
get_string = dll.get_string
get_string.argtypes = [C.c_char_p]
get_string.restype = C.c_char_p
in_str = C.create_string_buffer(1024,'\0')
out_str = get_string(in_str)
print("传入空字符串指针,返回字符串demo:")
print(in_str.value)
print(out_str)
运行结果:
windows下python调用含有opencv Mat类型的dll文件的方法
参考我的这篇文章:
windows下python调用含有opencv Mat类型的dll文件的方法