gpt4 book ai didi

c++ - 有没有更好的方法在 C++ 中加载 dll?

转载 作者:可可西里 更新时间:2023-11-01 12:40:32 25 4
gpt4 key购买 nike

现在我正在做这样的事情,如果我最终有很多我想在我的 DLL 中引用的函数,这看起来很乱。有没有更好更简洁的方法来访问函数而不必为每个函数定义创建 typedef 以便它可以正确编译和加载函数。我的意思是函数定义已经在 .h 文件中,我不应该在加载函数后重新声明它们(或者我这样做?)有没有比使用 LoadLibary 更好的解决方案?如果我可以在 Visual Studio 2005 项目设置中做同样的事情,我不一定需要该功能。


BHannan_Test_Class.h

#include "stdafx.h"
#include <windows.h>

#ifndef BHANNAN_TEST_CLASS_H_
#define BHANNAN_TEST_CLASS_H_

extern "C" {

// Returns n! (the factorial of n). For negative n, n! is defined to be 1.
int __declspec (dllexport) Factorial(int n);

// Returns true iff n is a prime number.
bool __declspec (dllexport) IsPrime(int n);

}

#endif // BHANNAN_TEST_CLASS_H_

BHannan_Test_Class.cpp

#include "stdafx.h"
#include "BHannan_Test_Class.h"

// Returns n! (the factorial of n). For negative n, n! is defined to be 1.
int Factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}

return result;
}

// Returns true iff n is a prime number.
bool IsPrime(int n) {
// Trivial case 1: small numbers
if (n <= 1) return false;

// Trivial case 2: even numbers
if (n % 2 == 0) return n == 2;

// Now, we have that n is odd and n >= 3.

// Try to divide n by every odd number i, starting from 3
for (int i = 3; ; i += 2) {
// We only have to try i up to the squre root of n
if (i > n/i) break;

// Now, we have i <= n/i < n.
// If n is divisible by i, n is not prime.
if (n % i == 0) return false;
}

// n has no integer factor in the range (1, n), and thus is prime.
return true;
}

dll_test.cpp

#include <BHannan_Test_Class.h>

typedef int (*FactorialPtr) (int);
FactorialPtr myFactorial=NULL;

// Tests factorial of negative numbers.
TEST(FactorialTest, Negative) {

HMODULE myDLL = LoadLibrary("BHannan_Sample_DLL.dll");

if(myDLL) {
myFactorial = (FactorialPtr) GetProcAddress(myDLL,"Factorial");

if(myFactorial)
{
EXPECT_EQ(1, myFactorial(-5));
EXPECT_EQ(1, myFactorial(-1));
EXPECT_TRUE(myFactorial(-10) > 0);
}

FreeLibrary(myDLL);
}

}

最佳答案

在 Windows 世界中,有(至少)4 种使用 DLL 的方法:

  1. Run-Time Dynamic Linking (你现在在做什么)
  2. Load-Time Dynamic Linking (使用 DLL 的“典型”方式)
  3. Delay-Load Dynamic Linking
  4. DLL Forwarding

我不必解释运行时动态链接,因为您已经在解释了。我选择不解释延迟加载动态链接,除了一般性地描述它是什么。延迟加载本质上与加载时动态链接相同,只是它是即时完成的,而不是在应用程序加载时完成的。这并不像您想象的那样有用或有益,它很难使用并且很难编写代码。所以我们不要去那里,至少现在不要去。 DLL 转发 甚至比延迟加载更奇特——如此奇特,直到@mox 在评论中提到它,我才听说过它。我会让你阅读上面的链接来了解它,但只要说 DLL 转发就是当你在一个 DLL 中调用一个导出函数但该请求实际上被转发到一个 DLL 中的另一个函数就足够了不同的 DLL。

加载时动态链接

这就是我认为的普通 DLL 链接

这是大多数人在提及在其应用程序中使用 DLL 时所指的内容。您只需#include DLL 的头文件并链接到LIB 文件。无需 GetProcAddress() 或创建函数指针类型定义。简而言之,它是如何工作的:

  1. 您通常会得到 3 个文件:一个包含运行时代码的 DLL、一个 LIB 文件和一个头文件。头文件只是一个头文件 -- 它描述了您可以使用的 DLL 中的所有功能。

  2. 您编写应用程序时,#include从 DLL 中获取头文件并调用这些函数,就像您在任何头文件中使用任何函数一样。编译器知道您使用的函数和对象的名称,因为它们在 DLL 的头文件中。但它还不知道它们在内存中的位置。这就是 LIB 文件的来源...

  3. 您转到项目的链接器设置并添加“附加库依赖项”,指定 LIB 文件。 LIB 文件告诉链接器您使用的 H 文件中的函数和对象在内存中的位置(显然是相对而言,而不是绝对术语)。

  4. 编译您的应用。如果您已正确设置所有内容,它应该可以编译、链接和运行。当您收到“未解析的外部引用”链接器错误时,通常这是由于设置不正确造成的。您可能没有指定正确的 LIB 文件路径,或者您需要包含更多 LIB 文件。

关于c++ - 有没有更好的方法在 C++ 中加载 dll?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2060403/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com