PDA

View Full Version : [C\C++] Chiamare funzione C++ da C


fdf86
15-10-2010, 10:01
ciao a tutti! Ho di nuovo bisogno del vostro aiuto.
Ho un simulatore che dispone di un modulo di comunicazione con C..È quindi in grado di convertire nel suo linguaggio una funzione scritta in C..
Questa funzione mi serve per ricevere un input esterno. Finora leggevo dal mouse e quindi bastava una funzione C..ora dovrà essere un device qualsiasi e dovrà leggere dati dal BUS..Questa parte è stata già implementata e funziona..il problema è che è scritta in C++..
Devo quindi scrivere una funzione C che riesca a ricevere dei dati (credo 2 o tre double) da quella funzione C++..
Potrei risolvere comunicando tramite socket ma dovrei avviare un'applicazione c++ durante la simulazione, o no?..Comunque preferirei che il programma di simulazione lavorasse, per così dire, da solo.
Premetto che non sono un programmatore..
per la tesi specialistica in ing Meccanica mi hanno catapultato in questo mondo che mi affascina molto ma che non conosco profondamente..
Ogni consiglio è ben accetto..
Grazie in anticipo,
Francesco

tuccio`
15-10-2010, 10:07
il C++ è un sovrainsieme del C, ragion per cui non puoi fare quello che dici

ps: comunque non ho capito... in che senso è stata già implementata in C++? cioè chi è che ha scritto sta roba in C++ se il simulatore compila (o interpreta?) solo C?

fdf86
15-10-2010, 10:31
io avevo pensato fosse impossibile ma speravo di sbagliarmi..
Cerco di spiegarmi meglio..
Si tratta di un progetto ampio..in pratica ci sono vari moduli che comunicano col BUS..per moduli intendo sia software di simulazione che device di input e/o output..
Per rendere tutto flessibile le comunicazioni di dati avvengono tramite BUS cosicché se si vuole cambiare device o simulatore è necessario solo passare al "nuovo arrivato" un config file con le informazioni che gli servono per ricevere ed inviare dati al BUS..
La parte finale, quella che permette di scrivere o leggere sul BUS, è anch'essa universale (scritta in C++ e richiama una JNI) ed in pratica fornisce delle classi che leggono o scrivono sul BUS..quindi dovrebbe essere in qualche modo aggiunta al o richiamata dal codice dello specifico "modulo"..
Spero di aver chiarito..
Quindi? Mi consigliate i socket?

fdf86
15-10-2010, 10:37
A ho dimenticato la parte importante :p ..
Il simulatore in question è OpenModelica..ed ha un suo linguaggio..semplicemente può chiamare una funzione C passandole degli argomenti che poi riottiene modificati (ad esempio)..
Io avevo pensato che la funzione C potesse a sua volta chiamare una funzione C++

tomminno
15-10-2010, 10:47
A ho dimenticato la parte importante :p ..
Il simulatore in question è OpenModelica..ed ha un suo linguaggio..semplicemente può chiamare una funzione C passandole degli argomenti che poi riottiene modificati (ad esempio)..
Io avevo pensato che la funzione C potesse a sua volta chiamare una funzione C++

funzioni C e C++ sono la stessa cosa.

Generalmente si usa C++ per poter sfruttare il paradigma della programmazione ad oggetti, ovvero strutturando il codice tramite classi.
Richiamare un metodo di una classe da C non è fattibile.

fdf86
15-10-2010, 10:58
Perdona l'ignoranza..
quindi da C non è possibile neppure richiamare una funzione C++ che usi una classe?..cioè sarebbe la stessa cosa che chiamare la classe direttamente da C?
O, essendo la stessa cosa, neppure le funzioni C++ possono richiamare metodi da classi?..non credo..

fdf86
15-10-2010, 11:13
Per intenderci..avevo intenzione di far qualcosa del genere..

http://developers.sun.com/solaris/articles/mixing.html#cpp_from_c


alla voce "Accessing C++ Classes From C"

tomminno
15-10-2010, 11:20
Perdona l'ignoranza..
quindi da C non è possibile neppure richiamare una funzione C++ che usi una classe?..cioè sarebbe la stessa cosa che chiamare la classe direttamente da C?


ma scusa il codice sarà comunque compilato all'interno dello stesso progetto e quindi sarà obbligatoriamente il progetto C++, non dovresti avere problemi particolari.


O, essendo la stessa cosa, neppure le funzioni C++ possono richiamare metodi da classi?..non credo..

Nella funzione istanzi un oggetto e richiami il metodo desiderato, ovviamente diventa una "funzione C++" in quanto utilizza caratteristiche proprie del C++.

fdf86
15-10-2010, 12:19
ma scusa il codice sarà comunque compilato all'interno dello stesso progetto e quindi sarà obbligatoriamente il progetto C++, non dovresti avere problemi particolari.

non è proprio così..come ho cercato di spiegare ogni modulo lavora da solo ed invia i risultati (o prende gli input) dal BUS.. è un'altra applicazione che gestisce il tutto..ma avvia semplicemente gli *.exe in pratica.. quindi a me servirebbe che il simulatore funzionasse da solo..l'unica differenza con la versione attuale è che l'input lo dovrà leggere da BUS tramite la classe già scritta invece che tramite la windows.h, come fa ora per prendere le coordinate del mouse.

tomminno
15-10-2010, 13:38
non è proprio così..come ho cercato di spiegare ogni modulo lavora da solo ed invia i risultati (o prende gli input) dal BUS.. è un'altra applicazione che gestisce il tutto..ma avvia semplicemente gli *.exe in pratica.. quindi a me servirebbe che il simulatore funzionasse da solo..l'unica differenza con la versione attuale è che l'input lo dovrà leggere da BUS tramite la classe già scritta invece che tramite la windows.h, come fa ora per prendere le coordinate del mouse.

Si ma cos'è questo Bus di preciso?
Se c'è un meccanismo di comunicazione remota, questo dovrebbe astrarre dal linguaggio specifico.

banryu79
15-10-2010, 14:02
Proviamo a fare chiarezza.
Ovviamente sto tentando di dare una mia intrepetazione (sto tirando a caso).
Ogni deduzione è marcata con un numero tra parentesi e rimanda a un quote per indicare da quali affermazioni è stata dedotta:

Sembra che esista una applicazione, chiamiamola X, che gestisce internamente una sorta di canale di comunicazione, chiamiamolo BUS (1), e che espone un'interfaccia (in C++?) (3) con cui delle applicazioni clienti terze, chiamiamole MODULI, possono comunicare/interagire scambiare dati con detto BUS (1).
Per connettersi al BUS in modo corretto, un MODULO deve conoscere i parametri del protocollo di comunicazione specificati in un file di configurazione fornito da X (2).

Forse X, l'applicazione che gestisce il BUS e ne fornisce l'accesso ai MODULI, è un'applicazione Java che però espone un'interfaccia in C++ (3).

(1)
Si tratta di un progetto ampio..in pratica ci sono vari moduli che comunicano col BUS..per moduli intendo sia software di simulazione che device di input e/o output..

(2)
Per rendere tutto flessibile le comunicazioni di dati avvengono tramite BUS cosicché se si vuole cambiare device o simulatore è necessario solo passare al "nuovo arrivato" un config file con le informazioni che gli servono per ricevere ed inviare dati al BUS..

(3)
La parte finale, quella che permette di scrivere o leggere sul BUS, è anch'essa universale (scritta in C++ e richiama una JNI) ed in pratica fornisce delle classi che leggono o scrivono sul BUS..quindi dovrebbe essere in qualche modo aggiunta al o richiamata dal codice dello specifico "modulo"..
Spero di aver chiarito..

Il problema dell'utente è che sta scrivendo l'implementazione di uno di questi MODULI in linguaggio C e deve interfacciarsi con X che espone un'interfaccia in C++.
E' corretto?

EDIT:
Ok, NON è corretto :asd:

fdf86
15-10-2010, 14:18
Non vorrei dirti stupidaggini..ma da quel che ho capito dovrebbe essere proprio il BUS fisico del computer..
come ti ho detto io non sono espertissimo..ma l'azienda in cui sto facendo lo stage si..mi hanno detto che è molto complicato comunicare col BUS direttamente e mi hanno solo accennato al funzionamento di quella parte in JNI di codice (credo sia coperta da segreto industriale tra l'altro).. insomma questo codice crea sul bus uno slot con il nome che vuoi e ci mette dentro la variabile (double o vettore di double) che vuoi iterativamente (sono simulazioni in tempo reale).. Il contenuto dello slot può poi essere letto sempre tramite questo blocco in JNI (basta sapere il nome della variabile e quindi dello slot)...
Comunque il punto non è questo..ho già fatto altri wrapper per altri moduli..
Il problema è che OpenModelica mette a disposizione al massimo un'interfaccia C (un po' come la Mex-Function di Matlab, almeno come concetto, non so se hai presente)..
Quindi se posso creare una funzione C++ che elabori dei dati utilizzando classi e richiamarla in C è ok..altrimenti devo passare i dati via socket..ovvero creo un'altra applicazione c++ che legge e scrive sul BUS ed invia i dati tramite protocollo tcp/ip alla funzione C..
Scusa se non sono chiarissimo e Grazie per l'aiuto comunque!

tomminno
15-10-2010, 14:39
Non vorrei dirti stupidaggini..ma da quel che ho capito dovrebbe essere proprio il BUS fisico del computer..


Ci deve essere un qualche protocollo di comunicazione software. Tra un software e un Bus fisico c'è un abisso nel mezzo almeno su computer, in ambienti embedded c'è comunque un protocollo gestito direttamente dal software. Come passano i dati su questo Bus?


Il problema è che OpenModelica mette a disposizione al massimo un'interfaccia C (un po' come la Mex-Function di Matlab, almeno come concetto, non so se hai presente)..


Scusa ma se OpenModelica espone una interfaccia C chi ti vieta di utilizzarla in un programma C++?

Bus -> Wrapper C++ -> C OpenModelica
C OpenModelica -> Wrapper C++ -> Bus

Suppongo che in quest'ultimo caso l'interfaccia di OpenModelica esponga delle funzioni che consentono di ricevere eventuali eventi (callback), se questa dovesse generare degli eventi spontanei.
Il C++ è stato creato appositamente con il (pesante) vincolo di essere compatibile con il C quindi non vedo che problemi tu possa avere nel farli convivere.

fdf86
15-10-2010, 14:42
Scusa banryu ma stavo già scrivendo quando hai postato..è in parte corretta ma è sicuramente colpa mia..
Diciamo che l'applicazione X non c'è..ogni modulo ha un suo .exe che funziona benissimo (se ci sono dei dati disponibili) da solo..
Vengono lanciati tutti i .exe.

Il BUS è come uno scaffale di documenti..Ogni modulo è un impiegato che riempie i suoi bei documenti e li mette in questo scaffale..
Se ad un altro modulo servono i documenti passa e li prende..(poi se non li trova si lamenta con crash o con messaggi... ma questo è un dettaglio)..
L'importante è che ogni impiegato metta (e prenda) quel che gli serve sullo (e dallo) scaffale.
L'applicazione JNI è lo strumento che mi hanno dato per scrivere sul BUS (che è proprio quello fisico)..potrei anche scrivere un codice che faccia lo stesso in Pascal (se ne fossi capace) ma capite che mi conviene utilizzare quello che ho (è un lavoro di anni)..

il problema quindi lo hai azzeccato comunque..io devo interfacciarmi con questa JNI che espone quest'interfaccia C++..poi sarà lei a fare avanti ed indietro verso lo scaffale ;)

fdf86
15-10-2010, 14:53
Ci deve essere un qualche protocollo di comunicazione software. Tra un software e un Bus fisico c'è un abisso nel mezzo almeno su computer, in ambienti embedded c'è comunque un protocollo gestito direttamente dal software. Come passano i dati su questo Bus?


e che ne so io!:cry: ..ti ho detto che non sono un luminare della programmazione..so che lo fa..ho il codice ma non posso studiarlo per ora..non ne ho il tempo e non so se lo capirei..non posso nemmeno passartelo sennò mi mettono in galera..


Scusa ma se OpenModelica espone una interfaccia C chi ti vieta di utilizzarla in un programma C++?

Bus -> Wrapper C++ -> C OpenModelica
C OpenModelica -> Wrapper C++ -> Bus

Il C++ è stato creato appositamente con il (pesante) vincolo di essere compatibile con il C quindi non vedo che problemi tu possa avere nel farli convivere.

È quel che chiedevo..all'inizio mi ero spiegato male forse e mi avevate detto che non si poteva fare..

banryu79
15-10-2010, 14:54
Ma sto JNI per cosa sta?
Non sarà mica Java Native Interface per caso?

tomminno
15-10-2010, 15:00
il problema quindi lo hai azzeccato comunque..io devo interfacciarmi con questa JNI che espone quest'interfaccia C++..poi sarà lei a fare avanti ed indietro verso lo scaffale ;)

Ok che ti devi interfacciare a JNI tramite C++, ma dovrai scrivere codice C++ per farlo!
Questo codice può sia richiamare le funzioni C di OpenModelica sia ovviamente l'interfaccia verso JNI.

tomminno
15-10-2010, 15:01
È quel che chiedevo..all'inizio mi ero spiegato male forse e mi avevate detto che non si poteva fare..

Eh non si capiva esattamente cosa volessi fare parlavi di richiamare da C del codice C++, mentre pare che tu debba da C++ richiamare codice C.

tomminno
15-10-2010, 15:02
Ma sto JNI per cosa sta?
Non sarà mica Java Native Interface per caso?

Suppongo proprio di si, evidentemente il gestore del bus è in Java.

fdf86
15-10-2010, 15:12
Ma sto JNI per cosa sta?
Non sarà mica Java Native Interface per caso?

Si sta proprio per Java Native Interface..lo avevo dato per scontato..chiedo venia

Eh non si capiva esattamente cosa volessi fare parlavi di richiamare da C del codice C++, mentre pare che tu debba da C++ richiamare codice C.

Avevo spiegato bene allora..era quello che intendevo fare..C++ da C..se è possibile ovvio!

io non voglio chiamare OpenModelica da C++..voglio mettere a disposizione della funzione C di OpenModelica una funzione che possa usare il wrapper C++..
Mi spiego meglio..Questa è la vecchia funzione C (per il mouse)

#include <windows.h>
#include <winuser.h>
#include <stdio.h>
#include "prova.h"

void importExt(int val, double* a,double* b)
{

POINT coord;

GetCursorPos(&coord);

int d;
d=prova();

*a=(coord.x)-1000;
*b=(coord.y);

FILE *stream;


stream=fopen("C:/Users/fdf/Desktop/car0/results.txt","a");


fprintf(stream,"%f \t %f \n",*a,*b);



fclose(stream);


return ;

}


Vorrei usare al posto della windows.h un mioC++.h che metta a disposizione una funzioni mioC++ (invece della GetCursor) che passi i due valori che mi servono..
Questi due valori dovrò però leggerli dal BUS usando sta famosa classe che mi danno..

È possibile questo?

P.S.: quella d=prova(); è la funzione c++ che provo a chiamare..ed è vuota per ora :P

tomminno
15-10-2010, 16:31
Avevo spiegato bene allora..era quello che intendevo fare..C++ da C..se è possibile ovvio!

io non voglio chiamare OpenModelica da C++..voglio mettere a disposizione della funzione C di OpenModelica una funzione che possa usare il wrapper C++..


Scusa ma come comunica OpenModelica con il tuo software?
Come registri il tuo software in OpenModelica? Ovvero come fai a far sapere ad OpenModelica dell'esistenza del tuo software?
O è il tuo software a richiamare l'interfaccia di OpenModelica?


Vorrei usare al posto della windows.h un mioC++.h che metta a disposizione una funzioni mioC++ (invece della GetCursor) che passi i due valori che mi servono..
Questi due valori dovrò però leggerli dal BUS usando sta famosa classe che mi danno..

È possibile questo?

P.S.: quella d=prova(); è la funzione c++ che provo a chiamare..ed è vuota per ora :P

Scusa ma il codice che hai postato è codice C++.
Se non hai vincoli esterni che ti impongono assolutamente l'utilizzo del C e te mi pare non li abbia, non c'è differenza tra C e C++.

In ogni caso hai fatto una prova?

fdf86
15-10-2010, 16:59
Il codice che ho postato non funziona..
funziona se commento la riga dove chiamo prova()..

scusa ma come fai a dire che è C++?:confused:
Io l'ho scritto convinto che fosse C..l'ho salvato come .c e l'ho passato ad OpenModelica che legge il solo C..

In OpenModelica va definita una funzione (nel suo linguaggio) in cui viene richiamata la funzione esterna C..la funzione C deve essere void..il passaggio di info avviene tramite gli argomenti..ecco il codice


function ExternalFunc1 //definition of function calling external C code
input Integer val;
output Real x;
output Real y;
annotation(Diagram(coordinateSystem(extent = {{ -100, -100},{100,100}})));
external importExt(val,x,y) annotation(Library = "libimportExt.o", Include = "#include \"importExt.h\"");
end ExternalFunc1;




e basta cambiare l'estensione del file da .c a .cpp e non funziona più..



Sto provando da due giorni a seguire le istruzioni nel link che ti ho postato ma nulla..
perciò mi è venuto il dubbio che non fosse possibile..anche se lì dice chiaramente "accedere ad una funzione c++ da codice C" ed addirittura ad una classe c++..
sto provando solo con visual studio e fare una cosa semplice ma nulla..ho un link error..forse sbaglio a compilare..:mc: