1 生成一个C/C++ 动态链接库
dlloutput.cpp 输出对外的接口函数
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "A.h"
#define DLLEXPORT extern "C" __declspec(dllexport)
static A A_a = A(); //定义一个A的静态变量操作类A中的函数
//两数相加 int
DLLEXPORT int A_add2(int a, int b) {
return A_a.add2(a,b);
}
//两数相加 int
DLLEXPORT int ADD1(int a, int b) {
return a + b;
}
//两数相减 float
DLLEXPORT float sub1(float a, float b) {
//printf("%f\n", a-b);
return a - b;
}
//两数相减 float
DLLEXPORT float mul(float a, float b) {
//printf("%f", a * b);
return a * b;
}
//传入int指针 返回int
DLLEXPORT int getNumber(int *a) {
*a = 2;
return *a+1;
}
//传入int指针 返回int
DLLEXPORT int getNumber2(int &a) {
a = 2;
return a + 1;
}
//传入int数组指针 返回int
DLLEXPORT int getsum(int *a,int n) {
int sum = 0;
for(int i = 0;i < n;i++)
{
sum += a[i];
}
return sum;
}
//传入int数组指针 返回int
DLLEXPORT int getsum2(int a[], int n) {
a[0] = 10;
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += a[i];
}
return sum;
}
//传入char数组指针 修改位置0的值
DLLEXPORT void updatechararray(char*a, int n) {
a[0] = 'a';
}
//传入字符 返回字符
DLLEXPORT char* getstring(char * f) {
return "hello world";
}
//对结构体的操作,
struct bbox_t {
unsigned int x, y, w, h; // (x,y) - top-left corner, (w, h) - width & height of bounded box
float prob; // confidence - probability that the object was found correctly 类的概率
unsigned int obj_id; // class of object - from range [0, classes-1] 类标签
unsigned int track_id; // tracking id for video (0 - untracked, 1 - inf - tracked object) 追踪视频的目标id
unsigned int frames_counter;// counter of frames on which the object was detected 目标被探测到的次数
};
#define C_SHARP_MAX_OBJECTS 1000
struct bbox_t_container {
bbox_t candidates[C_SHARP_MAX_OBJECTS];
};
//传入结构体的指针或者引用并修改其中的值
DLLEXPORT int updateBoxContainner(bbox_t_container &b) {
b.candidates[1].x = 100;
printf("%d", b.candidates[0].x);
return 1;
}
//传入结构体的指针或者引用并修改其中的值
DLLEXPORT int updatebox(bbox_t &b) {
b.x = 1020;
printf("%d", b.x);
return 1;
}
DLLEXPORT int updatebox2(bbox_t *b) {
b->x = 1020;
printf("%d", b->x);
return 1;
}
A.h 和A.cpp
//--------A.h
#pragma once
class A{
public:
int add2(int a,int b);
};
//--------A.cpp
#include "A.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include<windows.h>
#define DLLEXPORT extern "C" __declspec(dllexport)
int A::add2(int a, int b)
{
return a+b;
}
2 python使用ctypes 举例
https://docs.python.org/3.6/library/ctypes.html#structures-and-unions
mport os
import sys
import ctypes
from ctypes import *
from threading import Thread
import time
#载入接口 C:\Users\user\Documents\Visual Studio 2015\Projects\wxt1\x64\Release\wxt1.dll
#最好是绝对路径引用,如果使用的dll还引用了其他的dll,所有的引用的dll都需要放在同一个文件夹下或者系统目录下
path2=r"C:\Users\user\Documents\Visual Studio 2015\Projects\wxt1\x64\Release\wxt1.dll"
lib = ctypes.windll.LoadLibrary(path2)
# 传入int 相加,返回int 1,2 直接传入函数不需要类型转换,整形可以直接互相转换
print("1+2=",lib.ADD1(1,2))
print("1+2=",lib.A_add2(1,2))
# 传入float 相减 返回float
x1=c_float(1.0)#对于float 类型的必须指定
x2=c_float(2.0)
lib.sub1.restype=c_float #此处必须指定 返回类型是float
print("1-2=",lib.sub1(x1,x2))
# 1*2
lib.mul.restype=c_float #此处必须指定 返回类型是float
print("1*2=",lib.mul(c_float(1.0),c_float(2.0)))
#传入字符串 返回字符串
s1=b"hello" #字符串一定是转成bytes 这里再字符串前加上b
lib.getstring.restype=c_char_p #必须确定返回类型为:c_char_p
s2=str(lib.getstring(s1))
print("S:",s2)
#传入整数指针返回整数,并通过指针修改n的大小
n=c_int(1)
print(lib.getNumber(byref(n)))
print(n)
#传入整数引用返回整数,并通过指针修改n的大小
n=c_int(1)
print(lib.getNumber(byref(n)))
print(n)
#传入int 数组指针 返回总和,同时修改位置0的值
p=(c_int * 10)()
for i in range(10):
p[i] = i
print(lib.getsum2(p,10))
#print(lib.getsum2(byref(p),10)) 加上byref也可以
print(p[0])
#传入char[] 并修改位置0的值
p=(c_char * 10)()
for i in range(10):
p[i] = i
print(lib.updatechararray(p,10))
print(p[0],p[1],p[2],p[3])
#传入结构体并对结构体进行操作
# 按下面的方式定义结构体
C_SHARP_MAX_OBJECTS=1000
class bbox_t(Structure):
_fields_=[("x",c_uint),("y",c_uint),("w",c_uint),("h",c_uint)
,("prob",c_float),("obj_id",c_int),("track_id",c_int),("frames_counter",c_int)]
box=bbox_t()
# lib.updatebox2(byref(box)) #传入box的引用修改box C/C++中的函数无论是 传指针还是引用 使用byref都是可以的
lib.updatebox2(byref(box)) #传入box的指针修改box
print(box.x)
#结构体中放自定义结构体的数组增加测试复杂性
class bbox_t_container(Structure):
_fields_ = [("candidates",bbox_t * C_SHARP_MAX_OBJECTS)]
boxContainer = bbox_t_container()
lib.updateBoxContainner(byref(boxContainer)) #传入引用
print(boxContainer.candidates[1].x)
3 常见的问题
(1)传参错误的报错如下,检查传参类型,个数是否正确