Сборка динамической библиотеки в CLion (+ CMake)

Подскажите, пожалуйста, правильно ли я понимаю, что для получения DLL библиотеки в CLion достаточно вписать в CMake файл что-то вроде этого:

add_library(project_name SHARED src/library.cpp src/library.h)

Дело в том, что я именно это и вписал в CMakeLists.txt, но после сборки получаю библиотеку, которую не получается динамически подключить к другому проекту (для теста попробовал динамически подключить библиотеку libmariadb.dll - все работает, так что подключаю я правильно).

Также прилагаю код.

1. library.h

#pragma once

#ifdef MY_LIB
#define MY_LIB __declspec(dllexport)
#else
#define MY_LIB __declspec(dllimport)
#endif

extern "C" MY_LIB void testa(int a);
extern "C" MY_LIB bool testb();

2. library.cpp

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

void testa(int a) {
    std::cout << "This is 'A' function" << std::endl;
}

bool testb() {
    std::cout << "This is 'B' function" << std::endl;
    return true;
}

3. CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project (MY_LIB)

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pdb)

#-------------------- Create a library -----------------------------------------
#Generate the shared library from the library sources
#-------------------------------------------------------------------------------

include_directories("${PROJECT_SOURCE_DIR}/include")

add_library(${PROJECT_NAME}
        SHARED
        src/library.cpp
        )


include(GenerateExportHeader)
generate_export_header(${PROJECT_NAME})

4. Код программы, коей проверяю работу библиотеки. Запускаю ее и в консоли указываю имя библиотеки (включая .dll). Сама библиотека (название.dll) лежит в папке с этой программой (вместе с .exe файлом). Если закинуть любую другую dll библиотеку в эту же папку и в консоли ввести ее имя, то она успешно загружается (я не получаю сообщение "Library ... is not found"). Однако, если указать имя моей dll, то получаю сообщение об ошибке, что библиотека не загружена (... is not found).

#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>

using namespace std;

typedef int (*function)(int a);

std::wstring s2ws(const std::string& s) {
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

int main() {
    string name;
    cout << "Enter the name of library: ";
    cin >> name;

    wstring stemp = s2ws(name);
    LPCWSTR result = stemp.c_str();

    HMODULE hm = LoadLibrary(result);

    if (hm == NULL) {
        cout << "Library " << name << " is not found!" << endl;
        system("pause");
    }
    else {
        cout << "Library " << name << " is loaded" << endl;
        function testa= (function)GetProcAddress(hm, "testa");

        testa(321);
    }

    FreeLibrary(hm);

    _getch();
    return 0;
}

Спасибо!


Ответы (1 шт):

Автор решения: arrowd

Препроцессорный дефайн необходим, т.к. когда вы компиляете приложение, использующее DLL, ее функции должны быть аннотированы __declspec(dllimport), а когда компиляете саму DLL - __declspec(dllexport). Если вы написали экспорт и там, и там, то библиотека нормально скомпилится, а с приложением будут проблемы.

→ Ссылка