adopt vs You can export dynamic link libraries (dll file ) To others c++ project 、c# project 、python Project use . This case will realize vs Export project as dynamic link library , to c++ Project and python Project use . Involving global variables 、 function 、 Custom class export .
After the project is created, you will get the following structure , You can write the core code in dllmain.cpp Inside ( The original content can be ignored ), The header file information is written in pch.h Inside
The following contents can be copied to pch.h in ( The blogger's code involves cuda, So you need to configure the following cuda,cuda The configuration of can refer to libtorch Example of video memory management _ A flash of hope to my blog -CSDN Blog , You can also cuda Delete the relevant code ). The blogger defines the export of a global variable here 、 Two functions and a custom class .
#pragma once
//extern Indicates that the function is a global function , It can be called elsewhere
//“C” In accordance with the said C Language to compile and link python Import below dll Only support C function
//__declspec(dllexport) Tell the compiler that this is an export function
#ifdef BUILD_MYDLL
#define API_SYMBOL __declspec(dllexport)
#else
#define API_SYMBOL __declspec(dllimport)
#endif // BUILD_MYDLL
// Import library
#include <iostream>
#include <cuda_runtime_api.h>
// Export global variables
extern "C" API_SYMBOL int globa_times;
// The export function
extern "C" API_SYMBOL float get_cuda_use();
extern "C" API_SYMBOL int reset_cuda();
// Export class
extern "C" API_SYMBOL class MyClass
{
public:
MyClass();
~MyClass();
int FunSub(int a, int b);
private:
};
The key to the above code is extern "C" API_SYMBOL class_type fun_name; among API_SYMBOL It's a define The constant , The value in this project is __declspec(dllexport), Import this... In other projects dll The value of the library is __declspec(dllimport), This is based on the constant BUILD_MYDLL Automatically judged .
The following contents can be copied to dllmain.cpp in . Constant BUILD_MYDLL It is also defined in the following code .
// dllmain.cpp : Definition DLL Entry point to the application .
#include "pch.h"
using namespace std;
#define BUILD_MYDLL // Defined as an export function
int globa_times = 999;
float get_cuda_use()
{
size_t free_byte;
size_t total_byte;
cudaError_t cuda_status = cudaMemGetInfo(&free_byte, &total_byte);
if (cudaSuccess != cuda_status) {
printf("Error: cudaMemGetInfo fails, %s \n", cudaGetErrorString(cuda_status));
return float(-1.0);
}
else {
double free_db = (double)free_byte;
double total_db = (double)total_byte;
float used_db_1 = (total_db - free_db) / 1024.0 / 1024.0;
std::cout << "Now used GPU memory " << used_db_1 << " MB\n";
return float(used_db_1);
}
}
int reset_cuda() {
globa_times++;
cudaDeviceReset();
float res=get_cuda_use();
return int(res);
}
MyClass::MyClass()
{
std::cout << "MyClass init" << std::endl;
}
MyClass::~MyClass()
{
}
int MyClass::FunSub(int a, int b)
{
return a - b;
}
When I hit run , Dynamic link library can be generated (xxx.dll and xxx.lib).
c++ A project importing a dynamic link library usually requires a header file (.h file )、 The library files (.lib file )、 Dynamically linked files (.dll file ), In the above process xxx.dll and xxx.lib And .h It can be sorted out separately to form a directory . among , It should be noted that ,dll The file should be placed under the same level of the executable file ( Or will dll Add the path of the file to the system environment variable path in ).
Importing your own dynamic link library is the same as the normal library , The details are shown in the following figure . Besides , It also needs to be in the linker -》 Input -》 Configure... In additional dependencies dll_export.dll. Because bloggers use... When constructing their own dynamic link library cuda, Therefore, this project should also be configured cuda Environmental Science .
The test code is as follows
#include <iostream>
#include <pch.h>
int main()
{
globa_times = 66;
//print_cuda_use();
int res= reset_cuda();
std::cout << "Now CUDA mem = " << res << std::endl;
MyClass myc;
int sub = myc.FunSub(100, 10);
std::cout << "myc.FunSub(100, 10) = " << sub << std::endl;
return 1;
}
The running results are as follows , It can be seen that everything is normal
python Import dll The library only needs dll The file path is just , But when dll The file has other dependencies dll when , Need to use os.add_dll_directory Supplementary others dll The path of . In the following code lib.reset_cuda(), Is to call the first one c function , Release video memory .
import ctypes
import os
#os.environ['Path']+=r'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin'
#python3.7 Versions above use the following code to add dependencies dll The path of
os.add_dll_directory(r'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin')
lib = ctypes.cdll.LoadLibrary(os.getcwd()+ "/dll_export.dll")
#win32api.FreeLibrary(libc._handle) # It is found that the program cannot exit normally at the end of running dll, You need to explicitly release dll
lib.reset_cuda()
Bloggers use jupyter lab, So in executing the command , You can see the corresponding... In the console c++ Code output .
more python call c++ dll For the usage of the library, please refer to C/C++ Code generation DLL & Python call C/C++ Generated dll_ Red time blog -CSDN Blog _c Generate dll