1

I'm getting some trouble when trying to link a library dynamically.

I've searched by other topics and by wikis and found two interesting links:

However, when I try to link my library dynamically I get unresolved external in my applicationk, here are the files:

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

Parts of my code:

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();

And the load momment:

    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:

    }

So, the thing is... I don't wnat my application dependent of this dll, but if it has then the dll must be loaded, so I just didn't included the .lib file to the project and commented the following line.

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

The errors I've got:

[ilink32 Error] Error: Unresolved external '_VerProg' referenced from C:\USERS\USER\DOCUMENTS\PROJECT\WIN32\RELEASE\LOAD.OBJ

Since now, thaks a lot guys.

Community
  • 1
  • 1
mauroaraujo
  • 332
  • 1
  • 10
  • 23
  • @CaptainObvlious but I want to link the library dynamically, so the .dll file would't be necessary to run the program. – mauroaraujo Jan 10 '16 at 02:25

1 Answers1

1

Since you don't want to depend on the VerProg DLL, you don't want to call any of its functions directly in code. Remove all the externs for them. When you want to call them, after getting the function pointer with GetProcAddress, you then need to call the function thru that function pointer:

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

or, since you can call a pointer to a function directly:

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

The Info::Ver function should be removed. You can package all the exports you're calling in CriptLib in a class that can load the DLL once, have a function to check if the DLL was found and loaded, and call thru the function pointers.

When you call VerProg directly, the linker will need to resolve the symbol so you'll create a dependency on that DLL.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56