2016-08-15 3 views
1

J'essaie d'apprendre à utiliser la DLL Xerces-c-3.1.4. J'ai téléchargé la source et construit la DLL en utilisant le xerces-all.sln dans VS Studio Express 2015.'xercesc_3_1 :: XMLPlatformUtils :: Initialize' externe non résolu dans l'application de test C++ Builder

J'ai écrit une application VCL très simple (un bouton sur un formulaire). Cela donne trois erreurs de l'éditeur de liens:

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

Les causes possibles qui me viennent sont:

  • je fait une erreur lors de la construction de la DLL
  • Ne pas avoir besoin d'un fichier .def pour traiter avec VC++ nom mangling? Aucun dans le .sln fourni, cependant.
  • N'ai-je pas besoin d'appeler GetProcAddress pour toutes les fonctions DLL que j'utilise? Mais où puis-je trouver des modèles pour toutes les fonctions de la DLL?

Voici le code pour mon application test:

#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); 
     } 
    } 
} 

Répondre

1

Vous pouvez utiliser GetProcAddress() mais il est plus de travail pour votre code d'installation. Vous pouvez utiliser l'outil de ligne de commande tdump.exe de C++ Builder pour obtenir la liste des noms de fonctions exportés de la DLL.

Vous pouvez ou utiliser l'outil de ligne de commande implib.exe de C++ Builder, avec ou sans. def fichier, pour créer un fichier d'importation statique .lib pour la DLL, puis ajoutez ce fichier .lib à votre projet.

+0

Merci, Remy. Il semble que la solution utilise la convention d'appel __cdecl sans fichier DEF. J'ai donc exécuté impdef mydef.def xerces_c_3_1.dll, et reçu "Attention ...: pas d'exportations". Assez grande idée! Je vais continuer à creuser et à expérimenter et j'espère trouver le moyen de construire correctement. – Kathleen

+0

Pour ceux qui pourraient trouver ce fil dans le futur, la solution consistait à ne pas faire de suppositions sur les instructions de construction de Xerces. J'ai fait ce qu'ils ont recommandé pour "Borland" C++, en exécutant le fichier MAKE avec mon compilateur Embarcadero CX10 Seattle, et cela a fonctionné parfaitement. – Kathleen