Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Cross-Platform Dynamic Library Creation and Consumption in C++, C#, and Java

Tech 1

Creating Dynamic Libraries

Windows DLL Development

To create a Windows dynamic link library, start by establishing a DLL project. The core functionality is implemented in the source file:

#include "framework.h"

extern "C" __declspec(dllexport) int addValues(int x, int y) {
    return x + y;
}

BOOL APIENTRY DllMain(HMODULE module, DWORD callReason, LPVOID reserved) {
    switch (callReason) {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}

The corresponding header defines the exported function:

#ifndef FRAMEWORK_H
#define FRAMEWORK_H

#include <windows.h>

#endif

extern "C" __declspec(dllexport) int addValues(int x, int y);

Build the project in Release configuration to genertae the DLL file.

Linux Shared Object Creation

For Linux platforms, create a shared object file using:

extern "C" {
    int calculateSum(int first, int second) {
        return first + second;
    }
}

Compile this source to produce a .so file.

Consuming Libraries

C++ Application Integration

Create a new executable project and implement library loading:

#include <iostream>
#include <windows.h>

typedef int (*sumFunction)(int, int);

int main() {
    HMODULE libraryHandle = LoadLibrary(L"mathlibrary.dll");
    
    if (libraryHandle) {
        std::cout << "Library loaded successfully\n";
        sumFunction addFunc = (sumFunction)GetProcAddress(libraryHandle, "addValues");
        
        if (addFunc) {
            std::cout << "Function call result: " << addFunc(150, 250) << std::endl;
        } else {
            std::cout << "Function not found\n";
        }
        
        FreeLibrary(libraryHandle);
    } else {
        std::cout << "Failed to load library\n";
    }
    
    return 0;
}

Place the compiled DLL in the executable directory before running.

C# Integration

Define P/Invoke signatures for native library access:

using System.Runtime.InteropServices;

internal static class MathBridge
{
    private const string WindowsLibrary = "mathlibrary.dll";
    private const string LinuxLibrary = "libmathlibrary.so";
    
    [DllImport(WindowsLibrary, CallingConvention = CallingConvention.Cdecl)]
    public static extern int addValues(int operand1, int operand2);
    
    [DllImport(LinuxLibrary, CallingConvention = CallingConvention.Cdecl)]
    public static extern int calculateSum(int operand1, int operand2);
}

Consume the native functions in application code:

using System;

class Program
{
    static void Main()
    {
        int result = MathBridge.addValues(12, 1000);
        Console.WriteLine($"Computed sum: {result}");
        Console.ReadKey();
    }
}

Java Integration Using JNA

Implement Java interfaces to map native library functions:

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface WindowsMathLibrary extends Library {
    WindowsMathLibrary INSTANCE = 
        (WindowsMathLibrary) Native.loadLibrary("mathlibrary.dll", WindowsMathLibrary.class);
    
    int addValues(int first, int second);
}
import com.sun.jna.Library;
import com.sun.jna.Native;

public interface LinuxMathLibrary extends Library {
    LinuxMathLibrary INSTANCE = 
        (LinuxMathLibrary) Native.loadLibrary("libmathlibrary.so", LinuxMathLibrary.class);
    
    int calculateSum(int first, int second);
}

Main application logic for cross-platform execution:

public class Application {
    public static void main(String[] args) {
        String platform = System.getProperty("os.name").toLowerCase();
        int computationResult = 0;
        
        if (platform.contains("windows")) {
            computationResult = WindowsMathLibrary.INSTANCE.addValues(5, 6);
        } else if (platform.contains("linux")) {
            computationResult = LinuxMathLibrary.INSTANCE.calculateSum(5, 6);
        } else {
            System.out.println("Unsupported platform: " + platform);
        }
        
        System.out.println("Native function output: " + computationResult);
    }
}

Include JNA dependency in project configuraton:

<dependencies>
    <dependency>
        <groupId>com.sun.jna</groupId>
        <artifactId>jna</artifactId>
        <version>5.12.1</version>
    </dependency>
</dependencies>

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.