Python通过ctypes调用DLL

例程:Python通过ctypes调用DLL

此例程主要是用来备忘备查,记录一些常用的ctypes调用方式,包括:基本数据类型、指针、引用、数组、结构、类的书写方式。

ctypes官方资料

https://docs.python.org/3/library/ctypes.html

参考代码

C++代码

// PythonDll.cpp : Defines the exported functions for the DLL application.
//


#include "stdafx.h"
#include <stdio.h>
#include <opencv2/opencv.hpp>

#define _CRT_SECURE_NO_WARNINGS 
#define  _CRT_SECURE_NO_WARNINGS_GLOBALS
#pragma warning (disable: 4996)

using namespace std;
using namespace cv;

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int add(int a, int b);
int add(int a, int b)
{
	return a + b - 1;
}

DLLEXPORT char * sadd(char * a, char * b);
char * sadd(char * a, char * b)
{
	char c[1024];
	memset(c, 0, 1024);
	strcpy(c, a);
	char *p = (char *)(c + strlen(a));
	strcpy(p, b);
	return (char *)c;
}



DLLEXPORT void * imageResize(void * image, int h0, int w0, int channels, void * &dst, int h1, int w1, int inter = INTER_AREA)
{
	Size sz0(w0, h0);
	Size sz1(w1, h1);

	int type = CV_8UC1;
	if (channels == 3)
		type = CV_8UC3;

	Mat img(sz0, type, image);

	/*
		uchar* pxvec = img.ptr<uchar>(0);
		int count = 0;
		for (int row = 0; row < h0; row++)
		{
			pxvec = img.ptr<uchar>(row);

			for (int col = 0; col < w0 * channels; col++)
			{
					pxvec[col] = ((uchar *)image)[count++];
			}
		}
	*/

	imwrite("n1.jpg", img);
	Mat oa;
	resize(img, oa, sz1, inter);
	imwrite("n2.jpg", img);
	dst = (void *)malloc(sizeof(uint8_t)*h1*w1*channels);
	memcpy(dst, oa.data, sizeof(uint8_t)*h1*w1*channels);
	return dst;
}

DLLEXPORT void imageReizeRelease(void * data) {
	free(data);
}

typedef struct tagPerson {
	char name[20];
	char *nickname;
	char sex;
	float  height;
	int age;
} Person;

class BaseBox {
public:
	uint32_t  boxsize = 0;
	uint32_t  boxtype = 0;
};

DLLEXPORT int setPersonBox(Person p0, BaseBox bb0, Person &p1, BaseBox &bb1) {
	strcpy(p1.name, "bob baby");
	bb1.boxsize = 5;
	return 10;
}

Python代码

from ctypes import *
import numpy as np
import cv2
import os

dllpath = os.getcwd() + "/PythonDll.dll"
fd = cdll.LoadLibrary(dllpath)

x = fd.add(3, 2)

sadd = fd.sadd
sadd.argtypes = [c_char_p, c_char_p]
sadd.restype = c_char_p
# arg0 = bytes("Sam", "gbk")
# arg1 = bytes(" Sha", "gbk")
y = sadd("Sam Sha".encode("utf-8"), " ,Hello!".encode("utf-8"))
print(y.decode())

imageResize = fd.imageResize
imageReizeRelease = fd.imageReizeRelease

img1 = cv2.imread("dlrb.jpg")

h0, w0, channels = img1.shape[0:3]
print("height: {} , width: {}, channels: {}".format(h0, w0, channels))
h1 = (int)(h0 * 0.3)
w1 = (int)(w0 * 0.3)

arg1 = np.array(img1, dtype=np.uint8)
arg1 = arg1.ctypes.data_as(c_void_p)

# arg1 = img1.ctypes.data_as(c_void_p)

arg2 = pointer(c_uint8(0))
imageResize.restype = POINTER(c_uint8)
pointer = imageResize(arg1, h0, w0, channels, byref(arg2), h1, w1)
# array = np.array(np.fromiter(pointer, dtype=np.uint8, count=h1 * w1 * channels))
array = np.array(np.fromiter(arg2, dtype=np.uint8, count=h1 * w1 * channels))
img2 = array.reshape((h1, w1, channels))
cv2.imwrite("n.jpg", img2)
cv2.imshow("img2", img2)

imageReizeRelease(pointer)


CharArrayType = c_char * 20

class Person(Structure):
    _fields_ = [("name", CharArrayType),("nickname",c_char_p),("sex", c_char),("height", c_float),("age", c_int)]

class BaseBox(Structure):
    _fields_ = [("boxsize", c_int),("boxtype", c_int)]

setPersonBox = fd.setPersonBox
p0 = Person("sam".encode("utf-8"),"sam sha".encode("utf-8"),b'm',178.0,48)
bb0 = BaseBox(3,4)
p1 = Person("bob".encode("utf-8"),"bob sha".encode("utf-8"),b'm',188.0,22)
bb1 = BaseBox(7,8)
v = setPersonBox(p0,bb0,byref(p1),byref(bb1))

cv2.waitKey()
cv2.destroyAllWindows()

经验分享

VC调试DLL的设置

打开VC项目的Properties,配置Debugging的Command指向python.exe,Command Arguments指向demo.py,如果必要设置Working Directory。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值