【问题标题】:Windows - Loading library dynamically C++Windows - 动态加载库 C++
【发布时间】:2016-01-10 02:10:55
【问题描述】:

我在尝试动态链接库时遇到了一些麻烦。

我通过其他主题和 wiki 进行了搜索,发现了两个有趣的链接:

但是,当我尝试动态链接我的库时,我的 applicationk 中的外部无法解析,以下是文件:

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,所以我只是没有将 .lib 文件包含到项目中并注释下一行。

//#pragma comment (lib, "CriptLib.lib")

我遇到的错误:

[ilink32 错误] 错误:未解析的外部“_VerProg”引用自 C:\USERS\USER\DOCUMENTS\PROJECT\WIN32\RELEASE\LOAD.OBJ

从现在开始,感谢很多人。

【问题讨论】:

  • @CaptainObvlious 但我想动态链接库,因此运行程序不需要 .dll 文件。

标签: c++ dll c++builder firemonkey dynamic-linking


【解决方案1】:

由于您不想依赖 VerProg DLL,因此您不想直接在代码中调用它的任何函数。删除他们的所有外部。当你想调用它们时,在使用GetProcAddress 获取函数指针后,你需要通过该函数指针调用函数:

frmAbout->lblExtName->Text = "CriptLib V" + (*verified)();

或者,因为您可以直接调用指向函数的指针:

frmAbout->lblExtName->Text = "CriptLib V" + verified();

应该删除Info::Ver 函数。您可以将您在 CriptLib 中调用的所有导出打包到一个可以加载一次 DLL 的类中,有一个函数来检查是否找到并加载了 DLL,并通过函数指针调用。

当您直接调用 VerProg 时,链接器将需要解析符号,以便您创建对该 DLL 的依赖项。

【讨论】:

  • 谢谢,如果我想让它独立,我不能在 DLL 中使用类?
  • 重新表述我之前的问题,如果我不在运行时加载 DLL(并使我的程序独立于它),我不能使用类吗?
  • 再读一遍后我明白了。没有再解释的必要。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 1970-01-01
相关资源
最近更新 更多