Dealing with dynamic link library (DLL) files

Learn how to deal with a dynamic link library, but first, you should know what a DLL is.

Mohamed Magdy
9 min readDec 4, 2023

Definition of the DLL files.

DLL stands for “Dynamic Link Library.” It is a file format used for holding multiple codes and procedures for Windows programs. DLL files are essential components of software development, especially on the Windows operating system.

Here’s a breakdown of the key aspects:

Dynamic Linking

DLL files allow dynamic linking of code. Instead of compiling all the code into a single executable file, DLLs store code that multiple programs can use simultaneously. This promotes code reusability and efficient use of memory.

Shared Libraries

DLLs are shared libraries that contain code, data, and resources that can be used by multiple applications. This shared nature helps reduce redundancy in code and storage space, as the same DLL can be used by several programs.

Run-Time Loading

DLLs are loaded into memory at run-time, as opposed to static linking, where all the code is linked at compile-time. This dynamic linking allows programs to be more modular and enables updates or changes to specific components without affecting the entire application.

Extension of Functionality

DLLs often contain functions and procedures that provide additional functionality or services to applications. This makes it possible for developers to extend the capabilities of their software by linking to existing DLLs.

Separation of Concerns

DLLs help in separating the concerns of different parts of a program. For example, a DLL might contain code related to user interface elements, and another DLL might contain code for handling database operations. This separation can enhance code organization and maintenance.

Versioning and Updates

DLLs can be updated independently of the applications that use them. This is advantageous for fixing bugs, adding features, or addressing security issues without requiring changes to the entire application.

Common DLLs

Some DLLs are part of the Windows operating system, and others are created by third-party developers. Common DLLs provide a standardized set of functions that programs can use without having to include all the code in their executables.

After talking about the definition of the DLL and the key aspects, we should talk about common language runtime in C#.

Common Language Runtime (CLR) in C#.

Definition of CLR

The Common Language Runtime (CLR) is a core component of .NET Framework that manages the execution and the lifecycle of all .NET applications (code). It provides various services, including automatic memory management, exception handling, security, and type safety. When a .NET application is compiled, it generates an intermediate language code called Common Intermediate Language (CIL). The CLR is responsible for translating this CIL into machine code and managing the execution of the resulting program. The CLR also provides a platform for interoperability between different programming languages that target the .NET Framework. This means that a program written in one .NET language can easily use libraries written in another .NET language. Overall, the CLR is an essential component of the .NET Framework that enables developers to create robust, secure, and interoperable applications.

Key attributes of .NET CLR

As part of the Microsoft .NET Framework, the Common Language Runtime (CLR) is the programming (Virtual Machine component) that manages the execution of programs written in any language that uses the .NET Framework, for example, C#, VB.Net, F# and so on.

Programmers write code in any language, including VB.Net, C#, and F#, when they compile their programs into an intermediate form of code called CLI in a portable execution file (PE) that can be managed and used by the CLR. Then the CLR converts it into machine code to be executed by the processor.

The information about the environment, programming language, its version, and what class libraries will be used for this code are stored as metadata with the compiler that tells the CLR how to handle this code.

The CLR allows an instance of a class written in one language to call a method of the class written in another language.

Common Language Infrastructure (CLI)

The CLR code uses a common type system (CTS) that is based on a common language infrastructure (CLI).

CLI is a specification developed by Microsoft that describes the executable code and runtime environment. In simple terms this allows us to use various high-level programming languages on various machines without rewriting the code.

CLI is divided into four main components, Let’s expand them:

Common type system (CTS)

CTS defines some basic data types and every language that is designed for use with .NET framework should be able to match its data types to these defined basic data types. So when various languages are designed following CTS, they will be able to communicate with each other and this is nothing but cross-language interoperability or communication.

Common Language Specification (CLS)

CLS is a set of specifications that must be met by every language to be considered as .NET compliant. It is a subset of CTS types and a set of rules. Example: Elimination of pointers and multiple inheritance.

Metadata

Metadata gives information about all the classes and the class members defined in the assembly. You will learn later what an assembly means.

Virtual Execution System (VES)

VES loads and runs the programs that are compatible with the CLI using metadata. To make it clear, CLI is a set of specifications for a virtual operating system that is nothing but a Common Language Runtime (CLR).

After we know the definition of the DLL files and know what CLR is, now we will talk about dealing with the DLL using programming languages.

Dealing with DLL files.

Using C#

Now, we will deal with DLL file using C#, and to see how to deal with it we will two projects first project we will build it and when the project finishes the build there is a DLL file will be created, we will use visual studio 2022.

Step 1. Open visual studio -> create new project->class library(.NET framework)

After create our class library and I named ClassLibrary2_csh_test_dll and created a class inside it and I named Class1 and write a function that returns an integer value of summation between two numbers and It is name is sum__

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary2_csh_test_dll
{
public class Class1
{
public static int sum__(int a,int b)
{
int c = 0;
c = a + b;
return c;



}
}
}

Step 2. Check the project on debug -> click on Build -> click on build solutions

After build you can open your project folder, go to bin folder then debug then you will have the DLL file ClassLibrary2_csh_test_dll.dll

Step 3. now we will create a new C# console project like step 1. but we will choose console app

Now we have a C# console app with the name of Console_for_doc.

Step 4. Go to solution explorer -> Right click on dependencies -> Add project reference -> click on browse and go to your folder project and choose your DLL file

Now you can use the functionality inside your DLL.

using ClassLibrary2_csh_test_dll;// Your namespace name in your dll file
namespace Console_for_doc
{
public class Program
{
static void Main(string[] args)
{
int result = 0;
result=Class1.sum__(5, 6);//Class1 refers to class name in your dll
Console.WriteLine(result);
}
}
}

Using C++/CLI

In this section we will deal with DLL files using C++/CLI, we will create a C# project that create a DLL file like we did in the C# section in step 1. and step 2. , so now we will see how to create a C++/CLI project

Step 1. Open visual studio -> create new project->CLR console app(.NET framework)

you should choose the version of the framework between [3.5, 4.72,4.8] I choose 4.8 like the C# DLL it should be the same version.

Step 2. After we create our CLR console app (.NET framework) with the name to_test_csh_dll

Step 3. we will create a header file, Right click on header files folder from solution explorer -> Add item, I created a header file and called it Summation.h

Step 4. we will add the DLL file like we do in the section of C#.

Now we will made a function in the header that contains our function from the DLL.

#pragma once
#include <msclr/marshal_cppstd.h>
using namespace System;
using namespace ClassLibrary2_csh_test_dll; //your dll
namespace Summation
{

public ref class test_sum
{
public:
test_sum(){}
int^ Call_summ_func(int a, int b)
{
return Class1::sum__(a,b); //Class1 is your class in your dll
}
};

}

Now we are finish we can use the test_sum class in the main.

#include "pch.h"
#include "Summation.h"

using namespace System;

int main(array<System::String ^> ^args)
{
int^ result = 0;
Summation::test_sum^ instance = gcnew Summation::test_sum();
result=instance->Call_summ_func(4, 5);
System::Console::WriteLine(result);
return 0;
}

Using JAVA

There are many ways to deal with your DLL using java by using JNA, JNI & Javonet and there is another approach that you can use the EXE directly by using process builder.

In this section, we will talk about two approaches Javonet and process builder

First approach

We will use Javonet, It is a universal and here the link of their website if you want to read more in their documentations and you can download the JAR file of the library.

We will create a C# project that create a DLL file like we did in the C# section in step 1. and step 2.

After that we can open any IDE of java and add the JAR file, and then you can use the library.

package org.example;
import com.javonet.sdk.java.Javonet;
import com.javonet.sdk.internal.InvocationContext;
import com.javonet.sdk.internal.RuntimeContext;
public class Main {
public static void main(String[] args) {
Javonet.activate("your-session-id");
// create called runtime context
RuntimeContext calledRuntime = Javonet.inMemory().clr();
// set up variables
String libraryPath = "your-path-of-your-DLL";
//yourNamespaceName.yourClassName
String className = "TestClass.TestClass";
// load custom library
calledRuntime.loadLibrary(libraryPath);
// get type from runtime
InvocationContext calledRuntimeType = calledRuntime.getType(className).execute();
// invoke type's method
//MultiplyByTwo->your function name, 25->the parameters that this function takes
InvocationContext response = calledRuntimeType.invokeStaticMethod("MultiplyByTwo", 25).execute();
// get value from response
int result = (int) response.getValue();
// write result to console
System.out.println(result);
}
}

Second approach

In this approach we will use process builder, It is look like the first approach but in this approach we will not use the DLL, we will use the EXE file direct.

package org.example;

import java.io.BufferedReader;

import java.io.IOException;
import java.io.InputStreamReader;


public class Main {

public static void main(String[] args) {


ProcessBuilder builder = new ProcessBuilder("your-path-of-your-exe", "you-can-path-any-arguments");
try {
Process process = builder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Result: " + line);
}
} catch (IOException e) {
e.printStackTrace();
}


}
}

Using Python

In python there is more than one library to do this job, But I try Clr library and work with me and to use it is simple.

import clr
import sys
assembly_path=r"your-path-of-your-DLL"
sys.path.append(assembly_path)
clr.AddReference("your-path-of-your-DLL")
#from yourNamespaceName import yourClassName
from ClassLibrary2_csh_test_dll import Class1
#instance from your class
myclass=Class1()
#use the function
result=0
result=myclass.sum__(4,5)
print(f"Result is :{result}")

That is my whole experience to deal with the DLL files.

--

--

Mohamed Magdy

AI Engineer passionate about football analytics. I develop AI models to uncover insights from football data and drive better decisions in the beautiful game.