cmake 编译 c++ dll 的一个例子(更新2:增加 python 调用方法)
CMakeLists.txt
project(xxx) add_library(xxx SHARED xxx.cpp) add_executable(yyy yyy.cpp) target_link_libraries(yyy xxx)
xxx.h
#ifndef XXX_XXX_H #define XXX_XXX_H #endif #pragma once #ifdef BUILD_XXX_DLL #define IO_XXX_DLL __declspec(export) #else #define IO_XXX_DLL __declspec(import) #endif extern "C" { IO_XXX_DLL void hello(void); IO_XXX_DLL double sum(double a, double b); }
xxx.cpp
#define BUILD_XXX_DLL #include "xxx.h" #include <iostream> using namespace std; IO_XXX_DLL void hello(void) { cout<<"Hello from dll!\n"<<endl; } IO_XXX_DLL double sum(double a, double b) { cout<<"The sum of "<<a<<" and "<<b<<" is: "<<a + b<<endl; return a + b; }
yyy.cpp
#include <windows.h> #include <iostream> using namespace std; int main() { HINSTANCE h = LoadLibrary("C:\\Users\\Perelman\\.CLion2016.1\\system\\cmake\\generated\\xxx-4d5c076f\\4d5c076f\\Debug\\libxxx.dll"); typedef void (*p0)(void); p0 hello = (p0)GetProcAddress(h, "hello"); cout<<"Run hello:\n"<<endl; hello(); typedef double (*p1)(double, double); p1 sum = (p1)GetProcAddress(h, "sum"); cout<<"Run sum:\n"<<endl; sum(10.0, 12.0); FreeLibrary(h); return 0; }
yyy.py
import ctypes # 注意一,注意 64bit 32bit 的问题,如果出现 193 错误:%1 不是有效的Win32应用程序,则见编译器由 64bit 更换为 32bit 即可 # 注意二,由于 dll 里是 cdecl 接口(如 extern “C” __declspec(dllimport)),因此 python 里用 ctypes.CDLL 接口 h = ctypes.CDLL('C:\\Users\\Perelman\\.CLion2016.1\\system\\cmake\\generated\\xxx-4d5c076f\\4d5c076f\\Debug\\libxxx.dll') h.hello() # 注意三,python 里的数据要经过 ctypes 处理下 # 指明参数格式 h.sum.argtypes = (ctypes.c_double, ctypes.c_double) # 指明返回格式 h.sum.restype = ctypes.c_double print(h.sum(10.1, 3))