Utilisation d'une DLL visualstudio avec CBuilder Xe5
Salut à tous
Voilà ce petit post qui n'est pas une question mais plutôt une solution à un problème que j'ai eu et que j'ai pu résoudre en naviguant dans pas mal de post à droite et à gauche.
Si jamais il n' a pas ça place ici .Toutes mes excuses aux modérateurs et administrateurs :oops:
Voici le problème:
J'ai écris une DLL en C/C++ avec visual studio 2013 et je veux l'utiliser avec CBuilder Xe5.
Voici un extrait du .h et du .cpp de ma DLL (il s'agit de fonction très simple pour vérifier que ça marche).
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
// Le bloc ifdef suivant est la façon standard de créer des macros qui facilitent l'exportation
// à partir d'une DLL. Tous les fichiers contenus dans cette DLL sont compilés avec le symbole MADLL2_EXPORTS
// défini sur la ligne de commande. Ce symbole ne doit pas être défini dans les projets
// qui utilisent cette DLL. De cette manière, les autres projets dont les fichiers sources comprennent ce fichier considèrent les fonctions
// MADLL2_API comme étant importées à partir d'une DLL, tandis que cette DLL considère les symboles
// définis avec cette macro comme étant exportés.
#ifdef MADLL2_EXPORTS
#define MADLL2_API __declspec(dllexport)
#else
#define MADLL2_API __declspec(dllimport)
#endif
extern MADLL2_API int nMaDLL2;
MADLL2_API int fnMaDLL2(void); |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
// MaDLL2.cpp*: définit le point d'entrée pour l'application DLL.
//
#include "stdafx.h"
#include "MaDLL2.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
// Il s'agit d'un exemple de variable exportée
MADLL2_API int nMaDLL2=0;
// Il s'agit d'un exemple de fonction exportée.
MADLL2_API int fnMaDLL2(void)
{
return 42;
} |
Après compilation sous visual studio je récupère 2 fichiers MaDll2.lib et MaDll2.dll
Utilisé tel quel ça ne fonctionne pas j'ai des erreurs au niveau de l'édition de lien. Le fichier MaDll2.lib n'est pas lu par CBuilder. Il faut en construire un nouveau à partir du fichier MaDll2.dll avec l'utilitaire Implib.
Dans une fenêtre console entrez la commande suivante:
ImpLib -a MaDll2.lib et MaDll2.dll
De plus j'ai modifié le .h de la manière suivante
Code:
1 2 3 4 5 6 7 8 9 10 11
|
#ifdef MADLL2_EXPORTS
#define MADLL2_API __declspec(dllexport)
#else
#define MADLL2_API __declspec(dllimport)
#endif
extern "C" {
extern MADLL2_API int nMaDLL2;
MADLL2_API int fnMaDLL2(void);
} |
Et ça fonctionne. En espérant que ce petit post soit utile à certains
Quand ça a marché ça marche plus
Bonjour
Je relance ce post car ayant changé de version de visual studio (je suis en 2017) et de CBuilder (Je suis en RAD Studio 10 Seattle)
Plus rien ne fonctionne
Donc le .h de ma DLL
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
#pragma once
#ifdef _WINDLL
#define DLLDEC __declspec(dllexport)
#else
#define DLLDEC __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
DLLDEC int Test();
DLLDEC int fft(double *valreelIn, double *valimagIn, double *valreelOut, double *valimagOut, int nbval);
#ifdef __cplusplus
}
#endif |
Mon code C dans RAD STudio
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
// ---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop
#include "TestDLLMain.h"
#include "fastFFT.h"
// ---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
// ---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
}
// ---------------------------------------------------------------------------
void __fastcall TForm1::btnCalculClick(TObject *Sender) {
int ok=Test();
}
// --------------------------------------------------------------------------- |
Et voici l'erreur retournée:
[ilink64 Erreur] Error: Unresolved external 'Test' referenced from D:\PROJETS\C++\TESTCBUILDER\INTEGREDLL\WIN64\DEBUG\TESTDLLMAIN.O
Manifestement il n'arrive pas à trouver la fonction Test qui est dans ma DLL mais je n'arrive pas à comprendre pourquoi.
J'ai construit un .lib à partir de ma DLL avec ImpLib et j'ai ajouté ce .lib à mon projet
Une idée???