Integrating IP2Location C Library With D Programming Language

The aim of this guide is to demonstrate integrating the IP2Location C library within the D programming language. In our example, we will be using the Linux environment.

First of all, you will need to install the IP2Location C library.
Follow the instructions at https://ip2location.com/developers/c to install the IP2Location C library.

Next, install the D compiler on your Linux. We are using the DMD compiler.
Follow the instructions at https://dlang.org/download.html to install the DMD compiler.

Next, you will need to download the IP2Location BIN file.
Download at https://www.ip2location.com/database/ip2location

Extract out the BIN file and copy to the folder where you will store your D codes.

Creating the D codes

Create a text file called IP2Location.d and paste the following codes into it. Our example uses the DB24 BIN file.

The code does the following:

  1. Dynamically loads the IP2Location C library for use in the D codes.
  2. Exposing the required functions from the IP2Location C library.
  3. Initializing the IP2Location object with the specified BIN database path.
  4. Performing geolocation query for the specified IP address and displaying the results.
  5. Performs cleanup and unload the IP2Location C library.

NOTE: Modify the dbLit variable to store your own path to your BIN database file. Modify the ipAddressLit variable to store the IP address you wish to query.

module IP2Location;
 
import std.stdio;
import core.stdc.string;
import core.sys.posix.dlfcn;
 
extern (C)
{
    struct IP2Location {
        FILE *filehandle;
        ubyte databasetype;
        ubyte databasecolumn;
        ubyte databaseday;
        ubyte databasemonth;
        ubyte databaseyear;
        uint databasecount;
        uint databaseaddr;
        uint ipversion;
        uint ipv4databasecount;
        uint ipv4databaseaddr;
        uint ipv6databasecount;
        uint ipv6databaseaddr;
        uint ipv4indexbaseaddr;
        uint ipv6indexbaseaddr;
    }
 
    struct IP2LocationRecord {
        char* country_short;
        char* country_long;
        char* region;
        char* city;
        char* isp;
        float latitude;
        float longitude;
        char* domain;
        char* zipcode;
        char* timezone;
        char* netspeed;
        char* iddcode;
        char* areacode;
        char* weatherstationcode;
        char* weatherstationname;
        char* mcc;
        char* mnc;
        char* mobilebrand;
        float elevation;
        char* usagetype;
    }
 
    enum IP2Location_mem_type {
        IP2LOCATION_FILE_IO,
        IP2LOCATION_CACHE_MEMORY,
        IP2LOCATION_SHARED_MEMORY
    }
}
 
int main() {
    // load the IP2Location C library
    auto lib = dlopen("libIP2Location.so".ptr, RTLD_LAZY | RTLD_LOCAL);
 
    if (lib is null) {
        return -1;
    }
 
    // exposing the required functions from the IP2Location C library
    extern (C) IP2Location* function(const char* db) IP2Location_open = cast(IP2Location* function(const char* db))dlsym(lib, "IP2Location_open");
    extern (C) int function(IP2Location* loc, IP2Location_mem_type mem_type) IP2Location_open_mem = cast(int function(IP2Location* loc, IP2Location_mem_type mem_type))dlsym(lib, "IP2Location_open_mem");
    extern (C) int function(IP2Location* loc) IP2Location_close = cast(int function(IP2Location* loc))dlsym(lib, "IP2Location_close");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_country_short = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_country_short");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_country_long = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_country_long");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_region = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_region");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_city = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_city");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_isp = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_isp");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_latitude = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_latitude");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_longitude = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_longitude");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_domain = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_domain");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_zipcode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_zipcode");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_timezone = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_timezone");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_netspeed = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_netspeed");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_iddcode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_iddcode");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_areacode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_areacode");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_weatherstationcode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_weatherstationcode");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_weatherstationname = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_weatherstationname");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_mcc = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_mcc");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_mnc = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_mnc");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_mobilebrand = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_mobilebrand");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_elevation = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_elevation");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_usagetype = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_usagetype");
    extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_all = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_all");
    extern (C) void function(IP2LocationRecord* record) IP2Location_free_record = cast(void function(IP2LocationRecord* record))dlsym(lib, "IP2Location_free_record");
    extern (C) void function() IP2Location_delete_shm = cast(void function())dlsym(lib, "IP2Location_delete_shm");
    extern (C) ulong function() IP2Location_api_version_num = cast(ulong function())dlsym(lib, "IP2Location_api_version_num");
    extern (C) char* function() IP2Location_api_version_string = cast(char* function())dlsym(lib, "IP2Location_api_version_string");
 
    // the path to the IP2Location BIN database (modify this to your own path)
    string dbLit = "./IPV6-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-ISP-DOMAIN-NETSPEED-AREACODE-WEATHER-MOBILE-ELEVATION-USAGETYPE.BIN";
 
    // IP address to query (modify this to the IP address you wish to query)
    string ipAddressLit = "8.8.8.8";
 
    // converting string literal to char pointer for use with IP2Location functions
    const char *ipAddress = ipAddressLit.dup.ptr;
    const char* db = dbLit.dup.ptr;
 
    // initializing the IP2Location object with BIN database path
    IP2Location* IP2LocationObj = IP2Location_open(db);
    if (IP2LocationObj is null) {
        printf("Please install the database in the correct path.\n");
        return -1;
    }
 
    // uncomment this section if you want to load BIN database into cached memory
    // if (IP2Location_open_mem(IP2LocationObj, IP2Location_mem_type.IP2LOCATION_CACHE_MEMORY) == -1) {
        // printf("Unable to load data into cache memory.\n");
        // return -1;
    // }
 
    // uncomment this section if you want to load BIN database into shared memory
    // if (IP2Location_open_mem(IP2LocationObj, IP2Location_mem_type.IP2LOCATION_SHARED_MEMORY) == -1) {
        // printf("Unable to load data into shared memory.\n");
        // return -1;
    // }
 
    // performs IP2Location geolocation query for the specified IP address
    IP2LocationRecord* record = null;
    record = IP2Location_get_all(IP2LocationObj, ipAddress);
 
    // display results if IP address is found in the BIN database
    if (record is null) {
        printf("Unable to locate IP address in the current database.\n");
    }
    else {
        printf("IP Address: %s\n", ipAddress);
        printf("Country Code: %s\n", record.country_short);
        printf("Country Name: %s\n", record.country_long);
        printf("Region: %s\n", record.region);
        printf("City: %s\n", record.city);
        printf("ISP: %s\n", record.isp);
        printf("Latitude: %f\n", record.latitude);
        printf("Longitude: %f\n", record.longitude);
        printf("Domain: %s\n", record.domain);
        printf("ZIP Code: %s\n", record.zipcode);
        printf("Timezone: %s\n", record.timezone);
        printf("Netspeed: %s\n", record.netspeed);
        printf("IDD Code: %s\n", record.iddcode);
        printf("Area Code: %s\n", record.areacode);
        printf("Weather Station Code: %s\n", record.weatherstationcode);
        printf("Weather Station Name: %s\n", record.weatherstationname);
        printf("MCC: %s\n", record.mcc);
        printf("MNC: %s\n", record.mnc);
        printf("Mobile Brand: %s\n", record.mobilebrand);
        printf("Elevation: %f\n", record.elevation);
        printf("Usage Type: %s\n", record.usagetype);
        printf("API Version (String): %s\n", IP2Location_api_version_string());
    }
 
    // free any allocated memory
    IP2Location_free_record(record);
 
    // close BIN database file handle
    IP2Location_close(IP2LocationObj);
 
    // delete shared memory if it was used
    IP2Location_delete_shm();
 
    // unload the IP2Location C library
    if (dlclose(lib) == 0) {
        return 0;
    }
    else {
        return -1;
    }
}

Compiling the IP2Location.d

At the command prompt, run the following command:

dmd IP2Location.d

Run the program

At the command prompt, run the following command:

./IP2Location

You should see something like below if everything goes well.

D Programming Language

Was this article helpful?

Related Articles