A DLL (Dynamic Link Library) is executable code that is not directly executable like EXE files, but you have to call its implementations via function calls or API. A DLL file can have functions, classes, and variables that perform a specific task when called upon. Depending upon the functionality of a particular DLL file, you might have to load it at your application’s startup. DLL files are an efficient solution for keeping implementation separate from functionality.
DLL files can be helpful when the legacy system is implemented in C or C++ for performance and efficiency, and you want to access the features via a high-end language like Python. In this guide, we will first write C++ code, create its DLL file, and then access it via Python by creating a wrapper.
The guide is distributed in the following sections:
- First, we will set up Microsoft Visual Studio to create a DLL file
- Next, we will write C++ code and create its DLL file.
- Finally, we will create a Python wrapper to access the DLL file.
Now, without further ado, let’s move to the guide on how to create a C++ DLL file and call its functions via Python:
- First of all, you need to download and install Microsoft Visual Studio. I used Visual Studio 2022.
- Once it’s downloaded, you need to specify which workload you are going to work with. In this case, we are going to go with C++ distributions. After that, you can select individual components to download and install; it’ll save you space on your computer and your time as the distributions are pretty big and can range up to 20 GB.
- In this case, I went for “Desktop Development with C++,” as shown in the screenshot. Once you have downloaded the required code distribution to create a C++ DLL file. We need to create a new project.
- Go to File -> New Project -> Templates -> select C++ in the first window and Windows in the second dropdown. There, you would see an option to create a DLL file.
- Once you have selected the suitable options, give the name to the project, and we are good to start writing code now.
- Once the project is created, we can now write the C++ code in the .cpp file that we want to wrap.
Following is the C++ code. It has three functions:
- The first function prints a specified string when called from the Python Script.
- The second function is to add two numbers the user gave in the method arguments.
- The third function shows how we can send a string to a DLL file from Python Script and how we receive an argument as a string type from a DLL file. The third function is the main deal that shows us how to deal with parameter passing using the ctypes library of Python to a DLL file and how to get the return in the specified data type.
Make sure to use extern “C” while writing the C++ functions for the wrapper. Otherwise, during the compilation of the DLL file, the names of the methods would be changed, and you wouldn’t be able to access the functions in the DLL file. In addition, the DLL files, once compiled, cannot be opened in a text editor to look into the code.
// dllmain.cpp : Defines the entry point for the DLL application. #include "pch.h" #include <stdio.h>; extern "C" { __declspec(dllexport) void foo() { // here you could use managed and unmanaged code printf(" \n Hello World"); } } extern "C" { __declspec(dllexport) int Add(int a, int b) { // here you could use managed and unmanaged code { return a + b; } } } extern "C" { __declspec(dllexport) char* textreturn(const char* phrase, char* result, size_t resultMaxLength) { // here you could use managed and unmanaged code { _snprintf_s(result, resultMaxLength, _TRUNCATE, "Decorated <%s>", phrase); return result; } } }
Once you have written the code, the next step is to create a DLL file of that code.
How to create a DLL file of a C++ Code?
There are two options to create a DLL file, either you can do it from the IDE, i.e., Visual Studio 2022 itself, or you can use some commands to generate the DLL files. Both methods do require Visual Studio and its C++ distributions.
Create a DLL file via IDE:
In order to create the DLL file in Visual Studio, just build the solution.
Then, if there are no errors, you will be able to see the location of the DLL file in the logs.
It will probably be in the directory you specified to store the projects while creating the project -> \x64\Debug\testDll with the extension DLL.
Create DLL via Command Line:
First, you need to open the Visual Studio Command Line interface. You can do that with the following command:
Next, adjust the command concerning the location of Visual Studio on your PC.
C:\~\Microsoft Visual Studio 17.0.2\Common7\Tools\vsdevcmd
Now we have to set the include path and then run the following command to build the DLL file:
cl.exe /D_USRDLL /D_WINDLL testDLL.cpp /MT /link /DLL /OUT:testDLL.dll
.Now that we have the DLL file, it’s time to call its functions via Python Wrapper.
How to Access C++ DLL File via Python using Ctypes:
Ctypes is a handy library to access legacy code or C++/C#/C code. It allows you to define the parameters with respect to their data type interfaces in C and C++.
First of all, we need to create a Python script and import ctypes. You can get it done via the command line if you have Python installed on your PC, or you can use an IDE like PyCharm, etc.
Once you have created a Python file, let’s call it wrapper.py next step is to organize the files so you can access them via the code.
You need to copy the DLL file that we generated from Visual Studio and move it to a location where the Python file is, or you can move it anywhere where it can be accessed easily.
import ctypes #loading dll into memory DLLFile = ctypes.CDLL("dll/testDll.dll") #specify the path of the DLL file #Simple function call with no return type DLLFile.foo() #Passing integer type arguments and returning sum print("\nSum:" , (DLLFile.MyAdd(4,5))) print(DLLFile) #Passing a String to dll DLLFile.textreturn.argtypes = [ctypes.c_char_p,ctypes.c_char_p,ctypes.c_size_t] #defining the datatype of arguments DLLFile.textreturn.restype = ctypes.c_char_p #defining return type phrase = b"Hellloooooo" #b' used to specify its a byte string result = ctypes.create_string_buffer(100) res = DLLFile.textreturn(phrase,result,ctypes.sizeof(result)) print(res) print(result.value) """ functionProtoptype = ctypes.WINFUNCTYPE( ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_bool, ctypes.c_bool, ctypes.c_char, ctypes.c_char, ctypes.c_char ) functionparameters = (1050,0,0,True,True,"", 0, 0) functionAPI = functionProtoptype(("ShowNumber",DLLFile2),functionparameters) p1 = ctypes.c_int (1050) p2 = ctypes.c_int (0) p3 = ctypes.c_int (0) p4 = ctypes.c_bool(True) p5 = ctypes.c_bool (True) p6 = ctypes.c_char ("") p7 = ctypes.c_int (0) p8 = ctypes.c_int (0) functionAPI (ctypes.byref(p1),ctypes.byref(p2),ctypes.byref(p3), p4,p5,p6,ctypes.byref(p7),ctypes.byref(p8),) """
In the code above, first, we call the first function that we defined in the C++ file, then the second method that adds two numbers provided by the user. Finally, the third method takes an argument as a string type from the Python code, processes it, and then returns it back.
There is another function defined in the Python code, but it’s commented out. You can use it as a reference if you have different data types in your C++ function and want to access that type, e.g., bool type from Python code. It also explains how to set the parameters using ctypes and pass them by reference.
I hope this easy-to-understand and straightforward guide helped you. Suppose you have any questions or queries regarding how to create a C++ DLL file and call its functions via a Python script. Feel free to drop a comment below.