Retour calcul CPP par JNI

Résolu
HSylvio Messages postés 116 Date d'inscription jeudi 22 juillet 2004 Statut Membre Dernière intervention 14 juin 2012 - 12 mai 2006 à 16:16
HSylvio Messages postés 116 Date d'inscription jeudi 22 juillet 2004 Statut Membre Dernière intervention 14 juin 2012 - 19 mai 2006 à 13:54
Bonjour;
Mon probleme c'est un message qui bloque la compilation; ou plutot le création du .dll :
je lance :
\Dev-cpp\bin\gcc -o mabibjni.dll TestJNI.cpp TestJNI.def
et j'ai :
In file included from /Dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/backward/iostream.h:31, from TestJNI.cpp:3:
/Dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or instead of the deprecated header . To disable this warning use -Wno-deprecated.

(oui j'aime bien les cin>> et cout<< ... ca change rien ke jmette .h ou pas sinon ce warning.)
jusqu'ici tout va bien...

Warning: resolving _Java_TestJNI1_construit by linking to _Java_TestJNI1_construit@12
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups

jusqu'ici tout va bien...

C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0xd):TestJNI.cpp: undefined reference to `std::s
tring::size() const'
C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0x60):TestJNI.cpp: undefined reference to `std::
string::operator[](unsigned int) const'
C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0x9f):TestJNI.cpp: undefined reference to `std::
string::operator[](unsigned int) const'
C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0xce):TestJNI.cpp: undefined reference to `std::
string::operator[](unsigned int) const'
C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0x1ac):TestJNI.cpp: undefined reference to `std:
:cin'
C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0x1b1):TestJNI.cpp: undefined reference to `std:
:istream::getline(char*, int)'
C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0x1eb):TestJNI.cpp: undefined reference to `std:
:ios_base::Init::Init()'
C:\DOCUME~1\HOUSSE~1\LOCALS~1\Temp/ccqWaaaa.o(.text+0x206):TestJNI.cpp: undefined reference to `std:
:ios_base::Init::~Init()'
/mingw/lib/libmingw32.a(main.o)(.text+0x106):main.c: undefined reference to `WinMain@16'
collect2: ld returned 1 exit status

mais la je c pas d'où i me sort ca...

Bon maintenant j'm'en vais vous mettre mon code :

#include <jni.h>
#include <stdio.h>
#include
#include "TestJNI1.h"

JNIEXPORT jstring JNICALL
Java_TestJNI1_construit(JNIEnv *env, jobject obj, jdoubleArray argsFromJava) {
printf("On a recu ");

int arrayLength = env->GetArrayLength(argsFromJava);
printf(" %d elements : \n", arrayLength);

jdouble *t = env->GetDoubleArrayElements(argsFromJava, 0);
int i;
for(i = 0; i < arrayLength; i++){
printf("%d\t:\t\t%d\t\t\n", i,t[i]);
}

char ligne[1024+1];
cin.getline(ligne,sizeof(ligne));
return env->NewStringUTF(ligne);
}

Et pour le côté java :
class TestJNI1 {
static {
System.loadLibrary("mabibjni");
}

public static void main(String[] args) {
TestJNI1 tJC = new TestJNI1();
double[] toSend = {8.0,3.24,5.546,4.12,6.56,8.4,6.1,7.8974};
for(int i=0;i<toSend.length;i++)
{
System.out.println(toSend[i]);
}

String toPrint = "Retour : "+tJC.construit(toSend).toString();
System.out.println(toPrint);
}
public native String construit(double[] a);
}

sans oublier le TestJNI.def :
EXPORTS
Java_TestJNI1_construit
et le header auto genere....

Si qqun peut m'aider ca fait vraiment plaisir; quitte a poster un code qui fasse transiter des objets directement tant pis tant qu'ca marche bien...

Merci

9 réponses

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
13 mai 2006 à 16:09
Salut,

bon je ne dev pas sous win mais bon ce que j'ai fais fonctionne chez moi faudra surement adapter pour que ca tourne chez toi je te donne ce que j'ai fai en reprenant ton code

primo création du fichier java rien de bien méchant

public class TestJNI1 {
static {
System.loadLibrary("malibjni");
}

public TestJNI1(double [] tabD){
System.out.println("Retour : " + build(tabD));
}

public static void main(String[] args) {
double[] toSend = {8.0,3.24,5.546,4.12,6.56,8.4,6.1,7.8974};
for(double d : toSend)
System.out.println(d);
new TestJNI1(toSend);
}

public native String build(double[] a);
}

création du makefile (ce fichier est généré automatiquement par une de
mes applications en tenant compte des flags citué dans le make.conf de
ma distrib(gentoo oblige :D))


#emplacement des headers java
INCJAVA = /opt/sun-jdk-1.5.0.06/include

#nom de la lib
LIBTEST = ./libmalibjni.so

#recuperation du nom de mon compilo
CC = g++-3.4.6

#pour le clean
RMOBJ = @rm -f ./*.o
RMLIB = @rm -f ./*.so
RMJAVA = @rm -f ./*.class

#chaine de compilation avec mes ptites options
CHOST = i686-pc-linux-gnu
CFLAGS = -O3 -march=pentium-m -pipe -fomit-frame-pointer -I$(INCJAVA) -I$(INCJAVA)/linux -D$(CHOST)

#regle all qui permet de taper simplement make dans une console
all:$(LIBTEST)



# compilation du cpp et creation de la lib
$(LIBTEST): TestJNI.o
$(CC) -shared -o$(LIBTEST) *.o

#regle de compilation
./%.o:./%.cpp $(INCJAVA)/linux/jni_md.h $(INCJAVA)/jni.h ./TestJNI1.h
$(CC) $(CFLAGS) -c $< -o $@

#netoyage de tt
clean:
$(RMOBJ)
$(RMLIB)
$(RMJAVA)
javaH:
javac *.java && javah -jni TestJNI1

launch:
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH && java TestJNI1

maintenant création du .class et du .h
make javah

création du .cpp

#include <jni.h>
#include
#include "TestJNI1.h"

using namespace std;

char ligne[1024+1];//evite de declarer des tableaux dans une fonction

JNIEXPORT jstring JNICALL Java_TestJNI1_build(JNIEnv *env, jobject obj, jdoubleArray argsFromJava) {
cout << "On a recu ";

int arrayLength = env->GetArrayLength(argsFromJava);
cout << arrayLength << " elements : " << endl;

jdouble *t = env->GetDoubleArrayElements(argsFromJava, 0);
for(int i = 0; i < arrayLength; i++)
cout << i << "\t:" << "\t\t" << t[i] << endl;

cout << "Saisissez une chaine : ";
cin.getline(ligne,sizeof(ligne));

return env->NewStringUTF(ligne);
}

compilation de la partie cpp
make

lancement de l'application
make launch

resultat
8.0
3.24
5.546
4.12
6.56
8.4
6.1
7.8974
On a recu 8 elements :
0 : 8
1 : 3.24
2 : 5.546
3 : 4.12
4 : 6.56
5 : 8.4
6 : 6.1
7 : 7.8974
Saisissez une chaine : ddfefrf
Retour : ddfefrf

voila si tu as des soushi ou des probs de comprehenssion hesite pas.

WORA
3
HSylvio Messages postés 116 Date d'inscription jeudi 22 juillet 2004 Statut Membre Dernière intervention 14 juin 2012
15 mai 2006 à 16:05
Merci bcp d'avoir repondu; malheureusement je n'ai pas pu utiliser ton makefile parceque je dois travailler sur une station windows...
J'ai donc suivi tous tes conseils; nos codes sont les memes mais j'ai toujours des erreurs bien incompréhensibles a mon niveau...peut être que ca vient de mon make.bat (et oui a la bourrine) alors le voila:

javac ./TestJNI1.java
javah TestJNI1
\Dev-cpp\bin\g++ -c -I "C:\Progra~1\Java\jdk1.5~1\include" -I "C:\Progra~1\Java\jdk1.5~1\include\win32" -o TestJNI.o TestJNI.cpp
\Dev-cpp\bin\g++ -o mabibjni.dll TestJNI.cpp TestJNI.def

J'ai maintenant deux problemes suivant ce que je met dans mon .cpp :
D'abord la compilation me dit:
undefined reference to `WinMain@16'

(saloperie d'OS) alors j'ai mis un main :
int main(int argc, char *argv[])
{
system("PAUSE");
return 0;
}

et donc là la compil ne relache pas d'erreurs sinon les warnings normaux
C:\Javac++\Algo 0>\Dev-cpp\bin\g++ -o mabibjni.dll TestJNI.cpp TestJNI.def
Warning: resolving _Java_TestJNI1_construit by linking to _Java_TestJNI1_construit@12
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups

mais lorsque je lance "java TestJNI1" j'ai la joie de voir que ca ne fonctionne pas du tout :

C:\Javac++\Algo 0>java TestJNI1
8.0
3.24
5.546
4.12
6.56
8.4
6.1
7.8974
Lance l'algo...
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000, pid=2068, tid=2428
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode)
# Problematic frame:
# C 0x00000000
#
# An error report file with more information is saved as hs_err_pid2068.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#

Une idée qqun? Est-ce que ca peut venir du main? Pkoi y'en aurait pas besoin sous unix?
Si vous voulez voir le .log yaka dmander...
(Dsl d'etre bidon au point de poser encore des questions apres avoir consulté 1000 tutoriaux!!! )
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
15 mai 2006 à 17:54
Salut,

tu dis que tu mets un main...... alors que l'on soit sur la meme longueur
tu veux faire comuniquer du c/c++ dans du java ou l'inverse

cas 1 (du cpp a java) :
tu ne doit pas faire un exe qd tu veux allé dans ce sens mais une lib dyn soit une dll donc le dir à ton compilot, de plus
il me semble que les dll sous win doivent avoir un main dll genre :
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved);
regarde si avec ton compilot tu n'as pas l'option -shared en c/c++ tu dois dire ce que tu veux produire a ton compilot
une appli, une lib dynamique, une lib static et sous win tu doit preciser si tu veux une appli graphique ou console

cas 2 :
oriente tes recherche sur le site de sun et cherche le source invoke.c qui montre comment faire appel à du java dans du
C/C++


Note : sous win il y a plusieur sortent de main
le main pour les dll
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved);
le main console
int main( void ), int main( ..... )
le main pour les apli graphique
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)

WORA
0
HSylvio Messages postés 116 Date d'inscription jeudi 22 juillet 2004 Statut Membre Dernière intervention 14 juin 2012
18 mai 2006 à 17:49
Si je puis me permettre j'aurai encore quelques petites questions, avis aux amateurs de JNI :

       - Comment faut-il que je compile les classes utilisées par la classe lancée par java??

       - Est-il possible d'utiliser des classes déjà existantes (cad en fait transformer les jdouble en double normaux...) ou est-ce qu'il faut que j'utilise des jvariables dans toutes les classes que j'utilise sous la principale??

Merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
18 mai 2006 à 19:43
Salut,

tu pourrais etre plus precis stp?

WORA
0
HSylvio Messages postés 116 Date d'inscription jeudi 22 juillet 2004 Statut Membre Dernière intervention 14 juin 2012
19 mai 2006 à 09:14
Bah ca vient sûrement de mon makefile;
j'vais y bosser un peu et t'embêterai peut être si je perd trop de temps.

En tt cas t vraiment un gars (trop) généreux de conseils; je ne sais pas si on a un décalage horaire mais les gens compétents comme ca qui résolvent les problemes de prog. des autres a minuit (heure france metropolitaine), le samedi et tout je leur tire mon chapeau!!! C'est ton patron qui doit être content de t'avoir!!!
Sinon la réponse a la deuxième question est OUI : on peut caster des jdouble en double et donc réutiliser des parties de code en c++ (et ca ca fait plaisir!!!)             i m'rete plus qu'à arriver a compiler le tout en une seule dll.
0
HSylvio Messages postés 116 Date d'inscription jeudi 22 juillet 2004 Statut Membre Dernière intervention 14 juin 2012
19 mai 2006 à 12:03
Voila c'est arrangé grace à devCPP;
J'suis pas encore au point avec les makefileZ, heureusement qu'il y a des programmes qui vont bien pour ca...

Maintenant j'vais pouvoir bien m'amuser avec mon heuristique, enfin j'vais arreter de perdre du temps avec des erreurs de syntaxe tout ca tout ca....

En tt cas merci beaucoup de ton aide; je voulai dire "à charge de revenche" mais je suis pas sûr d'avoir grand chose a t'apprendre... j'imagine même pas ce ke ca doit être quand t bloké!

Merci encore!
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
19 mai 2006 à 12:41
Salut,

lol mais de rien ca fais plaisir d'aider le gens , pi bon pour mon partron effectivement il est assez fan sachant que je bosse les jours ferié , sinon si tu as d'autres soushi fais signe :D.

Pour ma par je ne suis pas bloqué souvent et honetement je prefere passer 3jours a chercher dans touts les sens avant de poster sur un forum :P

sinon pour te faire une idée cette semaine je me suis retrouvé bloqué sur un problème j'ai une fenetre en C++(win/linux/mac) qui prend la forme d'une image(la fenetre est skinable) de la j'ai voulu lui rajouter un JPanel en guise de content pane ba je te racompte pas l'usine a gaz pour remplacer un simple setContentPane

NOTE: si un jour les dev de sun peuvent implmenter cette fonction dans le jdk ca aiderai pour faire des appli reelement skinable sans avoir un rectangle tt laid en guise de fenetre .

WORA
0
HSylvio Messages postés 116 Date d'inscription jeudi 22 juillet 2004 Statut Membre Dernière intervention 14 juin 2012
19 mai 2006 à 13:54
      Je pense que tu fais partie des gens qui suivent le lancement de la version openSource de java avec beaucoup d'intérêt et que tu vas nous pondre un bon petit paquet d'améliorations...
Je suppose que tu as un site ou qqchose dans le genre non? Paske j'voudrais pas manquer ca!!

     Je pars (enfin) dans les joies randomimsme maintenant je peux commencer a être productif et faire de la métaheuristique dans tous les sens; MERCI QUI?!? merci Wora (twinuts?) et au plaisir!!
0
Rejoignez-nous