Aiuto per risolvere un problema con l'importazione di una funzione da una dll - pagina 2

 

Ho scritto qualcosa in un file h


extern __declspec( dllexport) int __stdcall GetIntValue(int);

poi nel cpp solo


int __stdcall GetIntValue(int)
 
Forse la parola chiave extern aiuterebbe.
 
alsu >> :

...


...e preferisco non avere a che fare con le corde... A che cosa servono in una tanica? È solo per bellezza?

E Borland stessa raccomanda di usare char* o char[], stile Metatrader, se necessario.

 

Credo che il modo corretto di dichiararlo nel costruttore sia il seguente (non ricordo esattamente)

extern "C" __declspec(dllexport) int __stdcall GetIntValue();

 
GarF1eld >> :

Penso che sia corretto dichiarare nel costruttore qualcosa come questo (non ricordo esattamente)

extern "C" __declspec(dllexport) int __stdcall GetIntValue();

Ecco! Esattamente!

 

Grazie mille per i consigli! Ha funzionato con questo esempio dopo extern "C" int __declspec(dllexport) __stdcall GetIntValue().

L'ho provato con le funzioni doppio e stringa, e ha funzionato anche. Ho deciso di applicare le conoscenze che ho acquisito da voi a un compito pratico. Ma ahimè... Non ci sono riuscito, purtroppo.

Se puoi, per favore aiutami ancora una volta.

Ci sono file nel progetto Bilder per la creazione di DLL: UHsvd.h, Usvd.cpp e altri.

Il file UHsvd.h ha una funzione che dovrebbe essere esportata in seguito:

bool rmatrixsvd(ap::real_2d_array a,
int m,
int n,
int uneededed,
int vtneededed,
int additionalmemory,
ap::real_1d_array& w,
ap::real_2d_array& u,
ap::real_2d_array& vt);

Il file Usvd.cpp contiene la stessa funzione, che dovrebbe quindi essere esportata:

bool rmatrixsvd(ap::real_2d_array a,
int m,
int n,
int uneededed,
int vtneededed,
int additionalmemory,
ap::real_1d_array& w,
ap::real_2d_array& u,
ap::real_2d_array& vt)

{

........

}

Inizio a costruire una DLL in Bilder in questa variante, tutto "costruisce", tutto funziona, nessun errore.

Se inizio a fare modifiche in UHsvd.h, Usvd.cpp come

extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(ap::real_2d_array a,

.....), allora gli errori da 2 a 19 appaiono con diverse varianti, cioè ho fatto questa dichiarazione o nel file header o in cpp... anche se da quanto ho capito dovrebbe essere nel file header (allora ci sono solo 2 errori):

[Errore BCC32] Usvd.cpp(128): E2356 Type mismatch in redeclaration of '__stdcall rmatrixsvd(ap::real_2d_array,int,int,int,int,ap::real_1d_array &,ap::real_2d_array &,ap::real_2d_array &)'
[errore BCC32] UHsvd.h(111): E2344 Dichiarazione precedente di '__stdcall rmatrixsvd(ap::real_2d_array,int,int,int,int,ap::real_1d_array &,ap::real_2d_array &,ap::real_2d_array &)'

Da quanto ho capito, c'è una discrepanza... Ma non lo capisco completamente... :-(

Spero davvero nel vostro aiuto e supporto...

 

boysn писал(а) >> {...}

Se puoi, per favore aiuta ancora una volta.

Ci sono file nel progetto Bilder per creare una DLL: UHsvd.h, Usvd.cpp e altri.

Il file UHsvd.h ha una funzione che deve essere esportata:

bool rmatrixsvd(ap::real_2d_array a,
int m,
int n,
int uneeded,
int vtneed,
int additionalmemory,
ap::real_1d_array& w,
ap::real_2d_array& u,
ap::real_2d_array& vt); {...}

Se ho capito bene, ap::real_1d_array è una classe. E ap::real_1d_array & è un riferimento a un oggetto di classe.

Ma caro, puoi solo passare doppio myData[] come parametri alla Dll,

che apparirà come doppio * nelle funzioni.

 
jartmailru писал(а) >>

Se ho capito bene, ap::real_1d_array è una classe. E ap::real_1d_array & è un riferimento all'oggetto della classe.

Ma caro, solo il doppio myData[] può essere passato alla Dll come parametro,

che nelle funzioni apparirà come doppio *.

Sono completamente d'accordo con te. Lo dichiarerò come doppio in MQL quando lo importerò. Ma al momento ho problemi a creare la DLL stessa in C++ Builder 2009. Ricevo errori durante la costruzione. Se non uso la dichiarazione

extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(ap::real_2d_array a, ...., ....) allora la libreria si compila in Bilder con successo, senza problemi. Ora, non so come creare correttamente la dichiarazione delle funzioni di esportazione nel progetto Bilder :-(, per ottenere

DLL funzionante con capacità di esportare la funzione rmatrixsvd.

 
boysn >> :

Sono totalmente d'accordo con te. Lo dichiarerò come doppio in MQL quando lo importerò. Ma al momento ho problemi a creare la DLL stessa in C++ Builder 2009. Ricevo errori durante la costruzione. Se non uso la dichiarazione

extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(ap::real_2d_array a, ...., ....) allora la libreria si compila in Bilder con successo, senza problemi. Ora, non so come creare correttamente la dichiarazione delle funzioni di esportazione nel progetto Bilder :-(, per ottenere

DLL funzionante con capacità di esportare la funzione rmatrixsvd.

Brrr. Sembra che lei sia stranamente d'accordo con me.

.

In realtà stiamo parlando di scrivere "adattatore" o "ponte".

"Adattatore" dal punto di vista che i parametri della funzione esportata

deve essere abbinato ai parametri che il metatrader può passare,

. cioè avete bisogno di una funzione extra che passi la chiamata dove volete che vada.

E "ponte" dal punto di vista che non è necessario per la funzione

che voi dichiarate farà il lavoro stesso.

E viceversa - non è necessario chiamare la funzione che fa il lavoro.

.

Cioè, è necessario separare l'interfaccia e l'implementazione, cioè l'implementazione può essere costruita su classi

. e funzioni che sono al di fuori della Dll di cui nessuno saprà mai nulla.

.

Ma consideriamo un esempio.

.

Dovreste dichiarare la funzione in questo modo:

extern "C" bool __declspec(dllexport) __stdcall RMatrixSVD_DLL_ADAPTER(double * in1, double * in2, double * out)

// naturalmente, passerete qui anche il numero di righe e colonne.

{

//convertire i parametri di input in ap::real_2d_array

ap::real_2d_array a1 = convertPDoubleToReal2DArray(in1);

ap::real_2d_array a2 = ;

.

//calcolare

ap::real_2d_array a3;

rmatrixsvd(a1, a2, a3);

.

//tradurre il risultato di a3 in out

convertReal2DArrayToPDouble(a3, out);

.

ritorno;
}

.

Qui - ovviamente - la funzione rmatrixsvd

non è dichiarato come extern "C" o __stdcall o __declspec ecc.

Perché fa parte dell'implementazione interna, nascosta.

 

Scusa, non ho capito bene, purtroppo...

Da http://alglib.sources.ru/ ho scaricato l'implementazione C++ (codice) di cui ho bisogno. Se non vi dispiace, date un'occhiata all'archivio allegato di 100KB. Questo algoritmo ha molte funzioni ausiliarie, il numero totale di linee di codice è qualcosa come 3000 linee... Penso di sì

Lo dice il sito web, cioè è troppo, ed è abbastanza difficile tradurlo in MQL... Bisogna capire l'algoritmo stesso per tradurlo correttamente. Al momento è un po' complicato per me. Ecco perché vorrei usare C++ Builder 2009 per fare una dll con questo codice già pronto e chiamare la funzione rmatrixsvd(...) di cui ho bisogno dalla dll. È qui che sono rimasto bloccato... dove e come dichiararlo correttamente... Con questo codice, senza cambiare una riga, la DLL viene costruita, senza errori. Ma appena ci metto dentro extern "C" bool __declspec(dllexport) __stdcall ottengo degli errori...

Grazie per il vostro tempo.

File:
svdy1e.cpp.zip  94 kb