1

I am trying to learn how to use the Xerces-c-3.1.4 DLL. I downloaded the source and built the DLL using the xerces-all.sln in VS Studio Express 2015.

I have written a very simple VCL app (a button on a form). This yields three linker errors:

Unresolved external 'xercesc_3_1::XMLPlatformUtils::Terminate()
Unresolved external 'xercesc_3_1::XMLUni::fgXercescDefaultLocale
Unresolved external 'xercesc_3_1::XMLPlatformUtils::Initialize()

The possible causes that occur to me include:

  • I did something wrong when building the DLL
  • Don't I need a .DEF file to deal with VC++ name mangling? None in the .sln provided, though.
  • Don't I need to call GetProcAddress for any DLL functions I use? But where can I find templates for all of the functions in the DLL?

Here's the code for my test app:

#ifndef MainFrmH
#define MainFrmH

#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

XERCES_CPP_NAMESPACE_USE


class TMainForm : public TForm
{
__published:    // IDE-managed Components
    TButton *InitButton;
    void __fastcall InitButtonClick(TObject *Sender);
private:    // User declarations
    HINSTANCE hXercesLib;
public:        // User declarations
    __fastcall TMainForm(TComponent* Owner);
    __fastcall ~TMainForm();
};

extern PACKAGE TMainForm *MainForm;

#endif

#include <vcl.h>
#include <iostream>
#pragma hdrstop

#include "MainFrm.h"

#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;

using namespace xercesc;

__fastcall TMainForm::TMainForm(TComponent* Owner)
    : TForm(Owner)
{
    hXercesLib = NULL;
} // ctor

__fastcall TMainForm::~TMainForm()
{
    if (hXercesLib)
    {
        XMLPlatformUtils::Terminate();
        FreeLibrary(hXercesLib);
        hXercesLib = NULL;
    }
} // dtor

void __fastcall TMainForm::InitButtonClick(TObject *Sender)
{
    if (!hXercesLib)
    {
        hXercesLib = LoadLibrary("xerces-c_3_1.dll");
        try
        {
            XMLPlatformUtils::Initialize();

            ShowMessage("XMLPlatformUtils::Initialize succeeded");
        }
        catch (Exception& e)
        {
            FreeLibrary(hXercesLib);
            hXercesLib = NULL;
            ShowMessage(e.Message);
        }
    }
}
Kathleen
  • 108
  • 7

1 Answers1

1

You can use GetProcAddress() but it is more work for your code to setup. You can use C++Builder's command-line tdump.exe tool to get a list of the DLL's exported function names.

You can alternatively use C++Builder's command-line implib.exe tool, with or without a .def file, to create a static import .lib file for the DLL, and then add that .lib file to your project.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks, Remy. It looks as if the solution used __cdecl calling convention with no DEF file. So I ran impdef mydef.def xerces_c_3_1.dll, and received "Warning ...: no exports". Pretty big clue! I'll keep digging and experimenting and hope to figure out to make this build correctly.. – Kathleen Aug 15 '16 at 20:12
  • For anybody who may find this thread in the future, the solution was for me not to make assumptions about the build instructions from Xerces. I did what they recommended for "Borland" C++, running the MAKE file with my Embarcadero CX10 Seattle compiler, and it worked perfectly. – Kathleen Aug 17 '16 at 16:03