CMakeLists.txt
project(virtual) # 创建工程 virtual add_library(virtual SHARED virtual.cpp) # 创建动态连接库 libvirtual.dll add_executable(main main.cpp) # 创建运行程序 main.exe target_link_libraries(main virtual) # 让 main.exe 连接 libvirtual.dllvirtual.h
#pragma once // 只编译一次 #ifndef VIRTUAL_VIRTUAL_H // 头文件定义 #define VIRTUAL_VIRTUAL_H #endif #ifdef BUILD_VIRTUAL_DLL // 导入导出标志,使其在 DLL 定义时声明为导出,再 DLL 调用时声明为导入 #define IO_VIRTUAL_DLL __declspec(export) // 导出定义 #else #define IO_VIRTUAL_DLL __declspec(import) // 导入定义 #endif extern "C" // 标准 C 格式,防止导出函数名变化 { IO_VIRTUAL_DLL char *hello(char *pChar); // 导出函数 hello }virtual.cpp
#define BUILD_VIRTUAL_DLL // 声明为导出 #include "virtual.h" // 包含头文件 class Base // 纯虚函数基类 { public: virtual char *hello(char *pChar) = 0; }; class Derived : public Base // 纯虚函数继承类 { public: char *hello(char *pChar); }; char *Derived::hello(char *pChar) // 继承类需写函数体,否则仍为纯虚类 { return pChar; } IO_VIRTUAL_DLL char *hello(char *pChar) // 导出函数定义,函数头为头文件导出名,函数体调用纯虚类以实例化 { Base *pClass; // 声明基类指针 pClass = new Derived(); // 指针初始化继承类 pClass->hello(pChar); // 实例化 }main.cpp
#include "virtual.h"#pragma comment(a, "C:UsersPerelman.CLion2016.1systemcmakegeneratedvirtual-2499818224998182Debuglibvirtual.dll.a")#include <iostream> using namespace std; int main() { cout << hello("Hello world! ") << endl; return 0; }virtual.py
import ctypes # extern "C" 格式的用 CDLL 加载库 hDLL = ctypes.CDLL("C:\Users\Perelman\.CLion2016.1\system\cmake\generated\virtual-24998182\24998182\Debug\libvirtual.dll") # 定义输入 C 格式 hDLL.hello.argtype = ctypes.c_char_p # 定义输出 C 格式 hDLL.hello.restype = ctypes.c_char_p # 返回指针 pointer = hDLL.hello("Hello world! ") print("pointer = ", pointer, " ") # 返回指针指向的值,取值 [pointer],解码 .decode("utf-8") value = [pointer][0].decode("utf-8") print("value = ", value, " ")