Bri*_*nan 10 c++ windows dll loadlibrary
现在我做这样的事情,如果我在我的DLL中有很多我想要引用的函数,它看起来很麻烦.是否有更好,更清晰的方式来访问函数,而无需为每个函数定义创建一个typedef,以便它可以正确地编译和加载函数.我的意思是函数定义已经在.h文件中,我不应该在加载函数后重新声明它们(或者我?)是否有比使用LoadLibary更好的解决方案?如果有一种方法可以在Visual Studio 2005项目设置中执行相同的操作,我不一定需要该功能.
#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_
Run Code Online (Sandbox Code Playgroud)
#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;
}
Run Code Online (Sandbox Code Playgroud)
#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);
}
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ing 22
在Windows世界中,有(至少)4种方式使用DLL:
我不必解释运行时动态链接,因为你已经在做了.我现在选择不解释延迟加载动态链接,而不只是描述它的概括性.延迟加载与加载时动态链接基本相同,除非它是实时的而不是在应用程序加载时完成的.这并不像你想象的那样有用或有益,它很难用来编写代码.所以,至少现在,我们不要去那里. DLL转发甚至比延迟加载更具异国情调 - 如此异国情调,我甚至从未听过它,直到@mox在评论中提及它.我会让你阅读上面的链接来了解它,但足以说DLL转发就是你在一个DLL中调用导出的函数但该请求实际上被转发到另一个DLL中的另一个函数.
这就是我认为的Vanilla DLL Linking.
这是大多数人在他们的应用程序中引用DLL时所指的内容.您只需#includeDLL的头文件并链接到LIB文件.无需GetProcAddress()或创建函数指针typedef.以下是它的工作原理:
1)您通常会得到3个文件:带有运行时代码的DLL,LIB文件和头文件.头文件只是一个头文件 - 它描述了你可以使用的DLL中的所有功能.
2)您编写应用程序,#include从DLL中获取头文件并调用这些函数,就像在任何头文件中使用任何函数一样.编译器知道您使用的函数和对象的名称,因为它们位于DLL的头文件中.但它还不知道它们在记忆中的位置.这就是LIB文件的用武之地......
3)转到项目的链接器设置并添加"附加库依赖项",指定LIB文件.LIB文件告诉链接器您在H文件中使用的函数和对象驻留在内存中(相对而言,显然不是绝对术语).
4)编译您的应用程序.如果你已经正确设置了一切,它应该编译,链接和运行.当您得到"未解析的外部引用"链接器错误时,这通常是由于未正确设置的.您可能没有指定LIB文件的正确路径,或者您需要包含更多LIB文件.
Dmi*_*try 10
构建.dll后,获取附近的.lib文件,并将测试应用程序与其链接.使用在.h中声明的函数
您需要在头文件中进行一些小改动:
#ifdef EXPORTS_API
#define MY_API_EXPORT __declspec (dllexport)
#else
#define MY_API_EXPORT __declspec (dllimport)
#endif
extern "C" {
int MY_API_EXPORT Factorial(int n);
// do the same for other functions
}
Run Code Online (Sandbox Code Playgroud)
这样,在构建您的dll时,您EXPORTS_API在项目设置和函数中定义导出,在客户端应用程序中,无需定义任何内容.
| 归档时间: |
|
| 查看次数: |
18235 次 |
| 最近记录: |