Linking my Dynamic Link Library to my CPP executable

I'm using CLion with cmake.

I want to link my dll to my c++ project in cmakelists.txt but I don't know how to do that.

I have searched a lot but I didn't find any solution.


  1. I have published a dll by visual studio in c++ which I want to link to my cmake project.
    • the project name and output name is Benchmark -> Benchmark.dll

here is the code: module.hpp

#pragma once
#ifdef CFAMILY_EXPORTS
#define CFAMILY_API __declspec(dllexport)
#else
#define CFAMILY_API __declspec(dllimport)
#endif

typedef std::chrono::steady_clock::time_point tpoint;
typedef std::chrono::seconds secs;
typedef std::chrono::milliseconds millis;
typedef std::chrono::microseconds micros;
typedef std::chrono::nanoseconds nanos;
using std::chrono::duration_cast;
const auto tnow = std::chrono::high_resolution_clock::now;

extern "C" {
    CFAMILY_API void ResetTimer();
    CFAMILY_API void StartTimer();
    CFAMILY_API void FinishTimer();
    CFAMILY_API long long GetTimer();
    CFAMILY_API long long GetTimerMillis();
    CFAMILY_API long long GetTimerMicros();
    CFAMILY_API long long GetTimerNanos();
}

module.cpp

#include "pch.h"
#include "module.hpp"

static auto start_time = tpoint();
static auto end_time = tpoint();

void ResetTimer()
{
    start_time = tpoint();
    end_time = tpoint();
}

void StartTimer() { start_time = tnow(); }

void FinishTimer() { end_time = tnow(); }

long long GetTimer() { return duration_cast<secs>(end_time - start_time).count(); }

long long GetTimerMillis() { return duration_cast<millis>(end_time - start_time).count(); }

long long GetTimerMicros() { return duration_cast<micros>(end_time - start_time).count(); }

long long GetTimerNanos() { return duration_cast<nanos>(end_time - start_time).count(); }
  1. then in my project in clion I want to use it:main.cpp
#include <iostream>
// include my benchmark.dll here and use its methods

int main() {
    // StartTimer(); in dll
    for (int i = 0; i < 1000000; i++) continue;
    // FinishTimer(); in dll
    // cout << GetTimerNanos() << endl;

    return 0;
}

cmakelists.txt

cmake_minimum_required(VERSION 3.17)
project(SpeedTest)

set(CMAKE_CXX_STANDARD 20)

add_executable(SpeedTest main.cpp)

find_library(${PROJECT_NAME}
    NAMES Benchmark
    HINTS "D:\\VS Projects\\BenchmarkLibrary\\C-Family\\Release-output\\x64")

Upvotes: 0

Views: 214

Answers (2)

I also found another solution that was about using Libloaderapi.h which is included in windows.h.

But I prefer using the way that @asmmo said

here is the code:

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

using namespace std;

typedef long long (__cdecl *long64F)();

typedef void (__cdecl *voidF)();

int main() {
    HMODULE hmodule = LoadLibraryA(R"(D:\VS Projects\BenchmarkLibrary\C-Family\Release-output\Win32\Benchmark.dll)");
    
    auto reset_timer = (voidF) GetProcAddress(hmodule, "ResetTimer");
    auto start_timer = (voidF) GetProcAddress(hmodule, "StartTimer");
    auto finish_timer = (voidF) GetProcAddress(hmodule, "FinishTimer");
    auto get_timer = (long64F) GetProcAddress(hmodule, "GetTimer");
    auto get_timer_millis = (long64F) GetProcAddress(hmodule, "GetTimerMillis");
    auto get_timer_micros = (long64F) GetProcAddress(hmodule, "GetTimerMicros");
    auto get_timer_nanos = (long64F) GetProcAddress(hmodule, "GetTimerNanos");
    
    cout << "for 1,000,000 times\n"
         << "---------------------" << endl;
    
    start_timer();
    for (int i = 0; i < 1000000; ++i) continue;
    finish_timer();
    
    cout << "time passed in secs:\t" << get_timer() << endl;
    cout << "time passed in millis:\t" << get_timer_millis() << endl;
    cout << "time passed in micros:\t" << get_timer_micros() << endl;
    cout << "time passed in nanos:\t" << get_timer_nanos() << endl;
    reset_timer();
    
    FreeLibrary(hmodule);
    return 0;
}

Upvotes: 0

asmmo
asmmo

Reputation: 7100

If the absolute directory of the .dll is "D:\\VS Projects\\BenchmarkLibrary\\C-Family\\Release-output\\x64", then you just need to add the following instead of find_library statement. it just searches for the library as the comment said.

target_link_directories(SpeedTest 
    PRIVATE
    "D:\\VS Projects\\BenchmarkLibrary\\C-Family\\Release-output\\x64"
)
target_link_libraries(SpeedTest PRIVATE Benchmark)
    

Update:

To call a function, use the header associated with your lib. include it using the absolute directory or edit your CMakeLists.txt file to add that directory and then use the name of the header i.e in your module.hpp, use #include"someHeader.hpp", then you can use the function declared in someHeader.hpp


To include the directory of your header, modify your CMakeLists.txt to add

target_include_directories(SpeedTest PRIVATE "The dir. of the header")

Upvotes: 1

Related Questions