如果我理解正确,请告诉我要在 CLion 中获取 DLL 库,只需在 CMake 文件中输入以下内容即可:
add_library(project_name SHARED src/library.cpp src/library.h)
事实是我在 CMakeLists.txt 中准确输入了这个,但是在组装后我得到了一个无法动态连接到另一个项目的库(对于测试,我尝试动态连接 libmariadb.dll 库 - 一切正常,所以我连接它正确)。
我也附上代码。
1.库.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.库.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)。库本身 (name.dll) 位于该程序所在的文件夹中(连同 .exe 文件)。如果我将任何其他 dll 库放入同一个文件夹并在控制台中输入其名称,则它会成功加载(我没有收到消息“库...未找到”)。但是,如果我指定我的 dll 的名称,我会收到一个错误,即库未加载(...未找到)。
#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;
}
谢谢!
预处理器定义是必要的,因为 当你编译一个使用 DLL 的应用程序时,它的函数必须用 注释
__declspec(dllimport)
,而当你编译 DLL 本身时,它的函数必须用__declspec(dllexport)
. 如果你在那里和那里都写了一个导出,那么库将正常编译,但应用程序会出现问题。