|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Junior Member
Iscritto dal: Oct 2006
Messaggi: 4
|
[Dll.... fatta in c++(Builder) richiamata in pascal(Delphi)]
Ciao a tutti, sono uno studente universitario ed ho un piccolo problema nel richiamare le funzioni contenute in una DLL fatta in C++ (CBuilder6) con una applicazione scritta in Pascal (Delphi6).
Di seguito riporto il codice scritto: #### file StaticLd.h ##################################### #ifndef _STATICLD_H #define _STATICLD_H #if defined __DLL__ # define DLL_EXP __declspec(dllexport) #else # define DLL_EXP __declspec(dllimport) #endif //------------------------------------------------------------------------ extern "C" void DLL_EXP Saluti(HWND); //------------------------------------------------------------------------ class DLL_EXP NomeClasse { public: NomeClasse(HWND hwnd); void FaQualcosa(char* text); void Beep(); private: HWND hWnd; }; //------------------------------------------------------------------------ #endif #################################################### ### ### #### file StaticLd.cpp #################################### //------------------------------------------------------------------------ #include <condefs.h> #include <windows.h> //------------------------------------------------------------------------ #pragma argsused #include "StaticLd.h" int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } //------------------------------------------------------------------------ void DLL_EXP Saluti(HWND hWnd) { MessageBox(hWnd, "Saluti da una funzione della DLL!", "Messaggio 1 per Filice", MB_OK | MB_ICONEXCLAMATION); } //------------------------------------------------------------------------ NomeClasse::NomeClasse(HWND hwnd) { hWnd=hwnd; } //------------------------------------------------------------------------ void NomeClasse::FaQualcosa(char* text) { MessageBox(hWnd, text, "Messaggio 2 per Filice",MB_OK); } //------------------------------------------------------------------------ void NomeClasse::Beep() { MessageBeep(-1); } //------------------------------------------------------------------------ Questa libreria chiamata in un'applicazione c++ funziona perfettamente. Riporto di seguito la Unit chiamante, composta da un Form con due pulsanti: #### file CallDll_Unit.h #################################### //------------------------------------------------------------------------ #ifndef CallDll_UnitH #define CallDll_UnitH //------------------------------------------------------------------------ #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //------------------------------------------------------------------------ class TForm1 : public TForm { __published: // IDE-managed Components TButton *Button1; TButton *Button2; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner); }; //------------------------------------------------------------------------ extern PACKAGE TForm1 *Form1; //------------------------------------------------------------------------ #endif #################################################### ### ### #### file CallDll_Unit.cpp ################################## //------------------------------------------------------------------------ #include <vcl.h> #pragma hdrstop #include "CallDll_Unit.h" #include "StaticLd.h" //------------------------------------------------------------------------ #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //------------------------------------------------------------------------ __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //------------------------------------------------------------------------ void __fastcall TForm1::Button1Click(TObject *Sender) { Saluti(Handle); } //------------------------------------------------------------------------ void __fastcall TForm1::Button2Click(TObject *Sender) { NomeClasse mc(Application->Handle); mc.FaQualcosa("Saluti da una funzione di una Classe della DLL!"); mc.Beep(); } //------------------------------------------------------------------------ //################################################## Mentre nel modulo in pascal, il compilatore non da nessun messaggio di errore però quando lo eseguo da il messaggio: " Impossibile trovare il punto di ingresso Saluti della procedura nella libreria di collegamento dinamico PrjStaticLd.dll." Riporto di seguito la Unit dell'applicazione chiamante in Pascal (approposito, mi limito a chiamare solo la funzione Saluti(.......)): #### file CallDllU.pas #################################### unit CallDllU; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var //-- fatta in CBuilder6 ----------------- procedure Saluti(hWnd : HWND ); external 'PrjStaticLd.dll'; //--------------------------------------- implementation {$R *.dfm} //################################################## //------------------------------------------------------------------------ procedure TForm1.Button1Click(Sender: TObject); begin Saluti(Handle); end; //------------------------------------------------------------------------ //################################################## end. So dell'esistenza dei modificatori "cdecl, pascal ecc..." per la compatibilità delle librerie ma non trovo materiale per studiarne il significato. Spero che qualcuno mi risponderà.... aiutooooooooo!!!!!!!!! |
|
|
|
|
|
#2 |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
un po' ovunque: quelli del compilatore Microsoft per esempio ovviamente sono documentati su MSDN. te ne riassumo brevemente le caratteristiche:
__stdcall - i parametri vengono messi (PUSH) nello stack da destra a sinistra, il cleanup viene fatto dal chiamato __cdecl - parametri messi da sinistra a destra, cleanup da parte del chiamante; permette di realizzare funzioni "vararg" (ellissi come ultimo "parametro" nel prototipo), al contrario di __stdcall che non lo permette __fastcall - utilizza i registri general purpose anziché lo stack per passare i primi parametri; se la funzione ha pochi parametri e non usa variabili locali non sarà necessario creare lo stack frame poi esistono anche __pascal, __fortran e __syscall, ma sono obsolete percui non le usare. |
|
|
|
|
|
#3 | |
|
Junior Member
Iscritto dal: Oct 2006
Messaggi: 4
|
[Grazie... ma mi servirebbero ulteriori informazioni]
Quote:
Per prima cosa grazie per avermi risposto. Il problema è che sono nuovo nella creazione delle dll e forse anche una stupidagine mi blocca, non riesco a capire perche durante l'esecuzione l'applicazione non trova il punto di ingresso alla funzione nella dll. Se ti và, potresti guardare il codice? Non è tanto, è solo un esempietto che ho preparato per l'occasione. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:56.



















