DEV Community

Cover image for How to Connect to DuckDB with C++
Marcos Oliveira
Marcos Oliveira

Posted on

1

How to Connect to DuckDB with C++

A fast and futuristic database for your projects.


We have already written an initial article about DuckDB that explains initial concepts, installation and first steps. For more information, access the link:

In this article, we will see how to connect to DuckDB using the API with C++


01. Download the lib and create a basic code

The DuckDB API for C++ is not yet stable, on the API page itself there is this warning:

DuckDB's C++ API is internal. It is not guaranteed to be stable and can change without notice. If you would like to build an application on DuckDB, we recommend using the C API.

That's why they recommend that you use the C API which works perfectly. To do this, just access the page: https://duckdb.org/docs/installation/ and choose the data according to your system. In my case, I chose:

Then just click on the .zip that will be made available and download it, or download it with wget:

wget -q https://github.com/duckdb/duckdb/releases/download/v1.3.0/libduckdb-linux-amd64.zip
Enter fullscreen mode Exit fullscreen mode

Unzip:

unzip libduckdb-linux-amd64.zip -d libduckdb-linux-amd64
Enter fullscreen mode Exit fullscreen mode

Create a database and table, example: duckdb terminalroot.db

CREATE TABLE terminalroot (id INTEGER, name STRING);
INSERT INTO terminalroot VALUES(1, 'Marcos Oliveira');
INSERT INTO terminalroot VALUES(2, 'Mark Raasveldt');
INSERT INTO terminalroot VALUES(3, 'Hannes Muhleisen');
SELECT * FROM terminalroot;
.exit
Enter fullscreen mode Exit fullscreen mode

Go into the directory you unzipped and create some basic code: cd libduckdb-linux-amd64/ && vim main.cpp

#include "duckdb.h"
#include <iostream>

int main(){
    duckdb_database db;
    duckdb_connection con;
    duckdb_result result;

    if(duckdb_open("terminalroot.db", &db) == DuckDBError){
        std::cerr << "Error opening database\n";
        return 1;
    }
    if(duckdb_connect(db, &con) == DuckDBError){
        std::cerr << "Error connecting to database\n";
        return 1; } 

    if(duckdb_query(con, "SELECT * FROM terminalroot;", &result) == DuckDBError){ 
        std::cerr << "Error executing SELECT\n"; 
        duckdb_disconnect(&con); 
        duckdb_close(&db); 
        return 1; 
    } 

    for(idx_t row = 0; row <= result.deprecated_column_count; row++){ 
        int id = duckdb_value_int32(&result, 0, row); 
        const char* name = duckdb_value_varchar(&result, 1, row); 
        std::cout << id << " | " << name << '\n'; 
        duckdb_free((void*)name); // free varchar memory 
    } 

    duckdb_destroy_result(&result); 
    duckdb_disconnect(&con);
    duckdb_close(&db);
}

Enter fullscreen mode Exit fullscreen mode

Compile and run:

g++ main.cpp libduckdb.so
LD_LIBRARY_PATH=. ./a.out
Enter fullscreen mode Exit fullscreen mode

Probable output:

1 | Marcos Oliveira
2 | Mark Raasveldt
3 | Hannes Muhleisen
Enter fullscreen mode Exit fullscreen mode

Install on the system

If you want to install on your system and compile with the -lduckdb flag, run the commands below:

  • 01. Move .h to include:
sudo mkdir -p /usr/local/include/duckdb
sudo cp duckdb.h /usr/local/include/duckdb/
Enter fullscreen mode Exit fullscreen mode
  • 02. Move the dynamic library to lib > And update the system's shared library cache.
sudo cp libduckdb.so /usr/local/lib/
sudo ldconfig
Enter fullscreen mode Exit fullscreen mode

After that, just test with the flag and you don't even need to be in the folder with the downloaded files or use the LD_LIBRARY_PATH environment variable:

But you need terminalroot.db, if you put the absolute path, e.g.: "/home/$USER/.db/terminalroot.db" your binary will run regardless of where you are in the system!

g++ main.cpp -lduckdb
./a.out
Enter fullscreen mode Exit fullscreen mode

If you want to create .pc for pkg-config, expand the procedure below:

Create the file /usr/local/lib/pkgconfig/duckdb.pc with this content:

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: DuckDB
Description: DuckDB embedded database
Version: 1.2.1
Libs: -L${libdir} -lduckdb
Cflags: -I${includedir}/duckdb
Enter fullscreen mode Exit fullscreen mode

Save with:

sudo mkdir -p /usr/local/lib/pkgconfig
sudo vim /usr/local/lib/pkgconfig/duckdb.pc
# paste the above content
Enter fullscreen mode Exit fullscreen mode

Refresh the cache:

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
Enter fullscreen mode Exit fullscreen mode

I tried the static library libduckdb_static.a, but had problems, but if you prefer, try:

g++ main.cpp libduckdb_static.a -I. -ldl -pthread -lm -lz -static-libstdc++ -static-libgcc
Enter fullscreen mode Exit fullscreen mode

If you also have problems, check for missing dependencies:

nm libduckdb_static.a | grep " U "
Enter fullscreen mode Exit fullscreen mode

("U" = undefined symbol)

Or use ldd ./a.out to see if there are still dynamic libs hanging.

In my case none of these steps worked, but see if they apply to you too.


Useful links

ACI image

ACI.dev: Best Open-Source Composio Alternative (AI Agent Tooling)

100% open-source tool-use platform (backend, dev portal, integration library, SDK/MCP) that connects your AI agents to 600+ tools with multi-tenant auth, granular permissions, and access through direct function calling or a unified MCP server.

Star our GitHub!

Top comments (0)

ACI image

ACI.dev: Fully Open-source AI Agent Tool-Use Infra (Composio Alternative)

100% open-source tool-use platform (backend, dev portal, integration library, SDK/MCP) that connects your AI agents to 600+ tools with multi-tenant auth, granular permissions, and access through direct function calling or a unified MCP server.

Check out our GitHub!

Join the Runner H "AI Agent Prompting" Challenge: $10,000 in Prizes for 20 Winners!

Runner H is the AI agent you can delegate all your boring and repetitive tasks to - an autonomous agent that can use any tools you give it and complete full tasks from a single prompt.

Check out the challenge

DEV is bringing live events to the community. Dismiss if you're not interested. ❤️