Link将我的动态 Link 库转换为我的 CPP 可执行文件
Linking my Dynamic Link Library to my CPP executable
我正在使用 CLion 和 cmake。
我想 link 我的 dll 到我 cmakelists.txt
中的 c++ 项目,但我不知道该怎么做。
我搜索了很多,但没有找到任何解决方案。
- 我已经用 visual studio 在 c++ 中发布了一个 dll,我想 link 到我的 cmake 项目。
- 项目名称和输出名称是
Benchmark
-> Benchmark.dll
代码如下: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(); }
- 然后我想在clion的项目中使用它:
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")
如果.dll
的绝对目录是"D:\VS Projects\BenchmarkLibrary\C-Family\Release-output\x64"
,那么只需要添加下面的内容,而不是find_library
语句。它只是按照评论所说搜索图书馆。
target_link_directories(SpeedTest
PRIVATE
"D:\VS Projects\BenchmarkLibrary\C-Family\Release-output\x64"
)
target_link_libraries(SpeedTest PRIVATE Benchmark)
更新:
要调用函数,请使用与您的库关联的 header。使用绝对目录包含它或编辑您的 CMakeLists.txt
文件以添加该目录,然后使用 header 的名称,即在您的 module.hpp
中,使用 #include"someHeader.hpp"
,然后您可以使用 someHeader.hpp
中声明的函数
要包含您的 header 的目录,请修改您的 CMakeLists.txt
以添加
target_include_directories(SpeedTest PRIVATE "The dir. of the header")
我还找到了另一个关于使用 Libloaderapi.h
的解决方案,它包含在 windows.h
.
中
但我更喜欢用@asmmo说的方式
代码如下:
#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;
}
我正在使用 CLion 和 cmake。
我想 link 我的 dll 到我 cmakelists.txt
中的 c++ 项目,但我不知道该怎么做。
我搜索了很多,但没有找到任何解决方案。
- 我已经用 visual studio 在 c++ 中发布了一个 dll,我想 link 到我的 cmake 项目。
- 项目名称和输出名称是
Benchmark
->Benchmark.dll
- 项目名称和输出名称是
代码如下: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(); }
- 然后我想在clion的项目中使用它:
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")
如果.dll
的绝对目录是"D:\VS Projects\BenchmarkLibrary\C-Family\Release-output\x64"
,那么只需要添加下面的内容,而不是find_library
语句。它只是按照评论所说搜索图书馆。
target_link_directories(SpeedTest
PRIVATE
"D:\VS Projects\BenchmarkLibrary\C-Family\Release-output\x64"
)
target_link_libraries(SpeedTest PRIVATE Benchmark)
更新:
要调用函数,请使用与您的库关联的 header。使用绝对目录包含它或编辑您的 CMakeLists.txt
文件以添加该目录,然后使用 header 的名称,即在您的 module.hpp
中,使用 #include"someHeader.hpp"
,然后您可以使用 someHeader.hpp
要包含您的 header 的目录,请修改您的 CMakeLists.txt
以添加
target_include_directories(SpeedTest PRIVATE "The dir. of the header")
我还找到了另一个关于使用 Libloaderapi.h
的解决方案,它包含在 windows.h
.
但我更喜欢用@asmmo说的方式
代码如下:
#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;
}