python3调用c++动态库(一)生成c++动态库

  • Post author:
  • Post category:python


本文介绍c++生成dll动态库,在win10系统,使用vs2017生成。



一、创建工程

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

说明:

  • AES.cpp和AES.h是实现AES加解密的文件
  • CAesDll.cpp和CAesDll.h是调用AES.h里面函数,封装成类CAes256
  • CApi.cpp和CApi.h是导出dll动态库的外部调用接口



二、封装AES加解密类

CAes256类,封装AES加解密功能:

#ifndef ENCRYPT_DECRYPT_H
#define ENCRYPT_DECRYPT_H
#include <string>

using namespace std;

class CAes256
{
public:
	CAes256();
	static void initAes(const string& key = "");
	static string encryptData(const string& dataIn);
	static string decryptData(const string& dataIn);
};

#endif // ENCRYPT_DECRYPT_H
#include "stdafx.h"
#include "CAesDll.h"
#include "AES.h"
#include <string.h>
#include <stdio.h>

typedef unsigned char UINT8;

UINT8 gAesKey[32] = { -84, 115, -48, 61, 3, 127, 34, 37, -73, -21, 85, 100, -4, 117, 63, 19 }; // t7CLWhtUTAgAFbw0

bool gInitFlag = false;

CAes256::CAes256()
{

}

void CAes256::initAes(const string& key)
{
	if (key != "") //t7CLWhtUTAgAFbw0
	{
		memset(gAesKey, 0x00, 32);
		memcpy_s(gAesKey, 16, key.c_str(), 16);
	}

	aesInit(gAesKey);
}

/*
*加密字符串
*/
string CAes256::encryptData(const string& dataIn)
{
	if (!gInitFlag)
	{
		gInitFlag = true;
		initAes("");
	}
	return aesBlockEncrypt(dataIn);
}

/*
*解密字符串
*/
string CAes256::decryptData(const string& dataIn)
{
	if (!gInitFlag)
	{
		gInitFlag = true;
		initAes("");
	}
	return aesBlockDecrypt(dataIn);
}



三、导出动态库外部调用函数

#ifndef CAPI_
#define CAPI_

#define CAPI_EXPORTS __declspec(dllexport)

#ifdef __cplusplus
extern "C" {
#endif
	
	CAPI_EXPORTS int my_add(int a, int b);
	CAPI_EXPORTS int my_sub(int a, int b);
	CAPI_EXPORTS int my_mul(int a, int b);
	CAPI_EXPORTS int my_div(int a, int b);
	CAPI_EXPORTS void init_aes(char* key); // 初始化aes密钥
	CAPI_EXPORTS char* aes_encrypt(char* str); // aes加密函数
	CAPI_EXPORTS char* aes_decrypt(char* enstr); // aes解密函数

#ifdef __cplusplus
}
#endif

#endif // CAPI_
#include "stdafx.h"
#include "CApi.h"
#include <iostream>
#include <string>
#include "CAesDll.h"

CAPI_EXPORTS int my_add(int a, int b)
{
	fprintf(stdout, "add operation\n");
	return a + b;
}

CAPI_EXPORTS int my_sub(int a, int b)
{
	fprintf(stdout, "sub operation\n");
	return a - b;
}

CAPI_EXPORTS int my_mul(int a, int b)
{
	fprintf(stdout, "mul operation\n");
	return a * b;
}

CAPI_EXPORTS int my_div(int a, int b)
{
	if (b == 0) {
		fprintf(stderr, "b can't equal 0\n");
		return -1;
	}

	return (a / b);
}

CAPI_EXPORTS void init_aes(char* key)
{
	if (key == NULL)
	{
		return;
	}

	CAes256::initAes(key);
}

CAPI_EXPORTS char* aes_encrypt(char* str)
{
	if (str == NULL)
	{
		return "";
	}

	string enstr = CAes256::encryptData(str);
	char* rst = new char[enstr.size() + 1];
	memcpy(rst, enstr.c_str(), enstr.size());
	rst[enstr.size()] = '\0';
	return rst;
}

CAPI_EXPORTS char* aes_decrypt(char* enstr)
{
	if (enstr == NULL)
	{
		return "";
	}

	string str = CAes256::decryptData(enstr);
	char* rst = new char[str.size() + 1];
	memcpy(rst, str.c_str(), str.size());
	rst[str.size()] = '\0';
	return rst;
}


重要说明:

  • 生成动态库时要选择debug/release
  • 可以选择生成x64(64位)和x86(32位)的动态库,外部调用时要选择对应位数的动态库,否则会提示”不是有效win32程序”



四、源码


本文源码



版权声明:本文为yyt593891927原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。