Windows - 动态加载库 C++
Windows - Loading library dynamically C++
我在尝试 link 动态库时遇到了一些麻烦。
我通过其他主题和 wiki 进行了搜索,发现了两个有趣的 link:
- Dynamically load a function from a DLL
- Tutorial: Using Dynamic Linked Libraries in C++Builder Applications
但是,当我尝试动态地 link 我的库时,我在我的应用程序中遇到了未解析的外部问题,这里是文件:
CriptLib.h:
#ifndef CriptLibH
#define CriptLibH
#ifdef CRIPTNSDLL_EXPORTS
#define CRIPTLIB_API __declspec(dllexport)
#else
#define CRIPTLIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
#include <fmx.h>
#include <FMX.Dialogs.hpp>
#include <System.Classes.hpp>
#include <string.h>
#include <FMX.Memo.hpp>
extern "C" {
#endif
CRIPTLIB_API void Cript_BasicoM(String Original, String Chave, TMemo* Memo);
CRIPTLIB_API void Cript_BasicoL(String Original, String Chave, TStringList* Lista);
CRIPTLIB_API void Cript_BasicoS(String Original, String Chave, String* Linha);
CRIPTLIB_API void Decript_BasicoM(String Chave, TMemo* Memo);
CRIPTLIB_API void Decript_BasicoL(String Chave, TStringList* Lista);
CRIPTLIB_API void Decript_BasicoS(String Original, String Chave, String* Linha);
CRIPTLIB_API String VerProg();
#ifdef __cplusplus
}
namespace CriptLib
{
class Encriptar
{
public:
static void Subst(String Original, String Chave, TMemo* Memo) { Cript_BasicoM(Original, Chave, Memo); }
static void Subst(String Original, String Chave, TStringList* Lista) { Cript_BasicoL(Original, Chave, Lista); }
static void Subst(String Original, String Chave, String* Linha) { Cript_BasicoS(Original, Chave, Linha); }
};
class Decriptar
{
public:
static void Subst(String Chave, TMemo* Memo) { Decript_BasicoM(Chave, Memo); }
static void Subst(String Chave, TStringList* Lista) { Decript_BasicoL(Chave, Lista); }
static void Subst(String Original, String Chave, String* Linha) { Decript_BasicoS(Original, Chave, Linha); }
};
class Info
{
public:
static String Ver() { return VerProg(); }
};
}
#endif
#endif
我的部分代码:
const wchar_t* library = L"CriptLib.dll";
typedef String (*VerInfoS)();
// Don't know if the following sentence is necessary once it is already declared in CriptLib.h (But I've also tried with it)
extern "C" __declspec(dllimport) String VerProg();
加载时间:
HINSTANCE load = LoadLibrary(library);
if (load) {
VerProgS verified = (VerProgS)GetProcAddress(load, "VerProg");
if (!verified) goto jump;
frmAbout->lblExtName->Text = "CriptLib V" + CriptLib::Info::Ver();
jump:
}
所以,问题是...我不希望我的应用程序依赖于此 dll,但如果它依赖于此 dll,则必须加载该 dll,所以我只是没有将 .lib 文件包含到项目中并评论了以下行。
//#pragma comment (lib, "CriptLib.lib")
我遇到的错误:
[ilink32 Error] Error: Unresolved external '_VerProg' referenced from
C:\USERS\USER\DOCUMENTS\PROJECT\WIN32\RELEASE\LOAD.OBJ
从现在开始,感谢了很多人。
由于您不想依赖 VerProg DLL,因此您不想在代码中直接调用它的任何函数。为他们删除所有外部人员。当你想调用它们时,在使用 GetProcAddress
获取函数指针后,你需要通过该函数指针调用函数:
frmAbout->lblExtName->Text = "CriptLib V" + (*verified)();
或者,因为您可以直接调用指向函数的指针:
frmAbout->lblExtName->Text = "CriptLib V" + verified();
应该删除 Info::Ver
函数。您可以将您在 CriptLib 中调用的所有导出打包在一个 class 中,它可以加载 DLL 一次,具有检查是否找到并加载 DLL 的功能,并通过函数指针调用。
当您直接调用 VerProg
时,链接器将需要解析该符号,以便您创建对该 DLL 的依赖。
我在尝试 link 动态库时遇到了一些麻烦。
我通过其他主题和 wiki 进行了搜索,发现了两个有趣的 link:
- Dynamically load a function from a DLL
- Tutorial: Using Dynamic Linked Libraries in C++Builder Applications
但是,当我尝试动态地 link 我的库时,我在我的应用程序中遇到了未解析的外部问题,这里是文件:
CriptLib.h:
#ifndef CriptLibH
#define CriptLibH
#ifdef CRIPTNSDLL_EXPORTS
#define CRIPTLIB_API __declspec(dllexport)
#else
#define CRIPTLIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
#include <fmx.h>
#include <FMX.Dialogs.hpp>
#include <System.Classes.hpp>
#include <string.h>
#include <FMX.Memo.hpp>
extern "C" {
#endif
CRIPTLIB_API void Cript_BasicoM(String Original, String Chave, TMemo* Memo);
CRIPTLIB_API void Cript_BasicoL(String Original, String Chave, TStringList* Lista);
CRIPTLIB_API void Cript_BasicoS(String Original, String Chave, String* Linha);
CRIPTLIB_API void Decript_BasicoM(String Chave, TMemo* Memo);
CRIPTLIB_API void Decript_BasicoL(String Chave, TStringList* Lista);
CRIPTLIB_API void Decript_BasicoS(String Original, String Chave, String* Linha);
CRIPTLIB_API String VerProg();
#ifdef __cplusplus
}
namespace CriptLib
{
class Encriptar
{
public:
static void Subst(String Original, String Chave, TMemo* Memo) { Cript_BasicoM(Original, Chave, Memo); }
static void Subst(String Original, String Chave, TStringList* Lista) { Cript_BasicoL(Original, Chave, Lista); }
static void Subst(String Original, String Chave, String* Linha) { Cript_BasicoS(Original, Chave, Linha); }
};
class Decriptar
{
public:
static void Subst(String Chave, TMemo* Memo) { Decript_BasicoM(Chave, Memo); }
static void Subst(String Chave, TStringList* Lista) { Decript_BasicoL(Chave, Lista); }
static void Subst(String Original, String Chave, String* Linha) { Decript_BasicoS(Original, Chave, Linha); }
};
class Info
{
public:
static String Ver() { return VerProg(); }
};
}
#endif
#endif
我的部分代码:
const wchar_t* library = L"CriptLib.dll";
typedef String (*VerInfoS)();
// Don't know if the following sentence is necessary once it is already declared in CriptLib.h (But I've also tried with it)
extern "C" __declspec(dllimport) String VerProg();
加载时间:
HINSTANCE load = LoadLibrary(library);
if (load) {
VerProgS verified = (VerProgS)GetProcAddress(load, "VerProg");
if (!verified) goto jump;
frmAbout->lblExtName->Text = "CriptLib V" + CriptLib::Info::Ver();
jump:
}
所以,问题是...我不希望我的应用程序依赖于此 dll,但如果它依赖于此 dll,则必须加载该 dll,所以我只是没有将 .lib 文件包含到项目中并评论了以下行。
//#pragma comment (lib, "CriptLib.lib")
我遇到的错误:
[ilink32 Error] Error: Unresolved external '_VerProg' referenced from C:\USERS\USER\DOCUMENTS\PROJECT\WIN32\RELEASE\LOAD.OBJ
从现在开始,感谢了很多人。
由于您不想依赖 VerProg DLL,因此您不想在代码中直接调用它的任何函数。为他们删除所有外部人员。当你想调用它们时,在使用 GetProcAddress
获取函数指针后,你需要通过该函数指针调用函数:
frmAbout->lblExtName->Text = "CriptLib V" + (*verified)();
或者,因为您可以直接调用指向函数的指针:
frmAbout->lblExtName->Text = "CriptLib V" + verified();
应该删除 Info::Ver
函数。您可以将您在 CriptLib 中调用的所有导出打包在一个 class 中,它可以加载 DLL 一次,具有检查是否找到并加载 DLL 的功能,并通过函数指针调用。
当您直接调用 VerProg
时,链接器将需要解析该符号,以便您创建对该 DLL 的依赖。