Page 3 of 21
Posted: 14 Oct 2007, 13:33
by hoijui
..in the meantime...
there are two issues i have that might have an impact on this.
1. the swig generated wrap code tries to redeclare long, and i get a compile error.
when i remove the following lines from JAI_wrap.cxx,
Code: Select all
/* Fix for jlong on some versions of gcc on Windows */
#if defined(__GNUC__) && !defined(__INTELC__)
typedef long long __int64;
#endif
it compiles fine.
2. [Edit: solved!, look at end of message] i am linking against jvm.dll (there is also a jvm.lib; i dont know hte difference, but i think it should be jvm.dll).
i use the latest stable release of the JDK (1.6.0_03) on windows (test system) and on linux (build system).
i mounted the jdk directory of the windows machine on my linux machine.
..so i link against the windows jvm with -ljvm.
in the code, i have to include jni.h, which includes jni_md.h, which is OS dependent. the dir structure is as folows:
jdk/include/jni.h
jdk/include/<os>/jni_md.h
(<os> is linux on linux, and win32 on the windows jdk)
when i use -I..../jdk/include/win32, i later get an error when linking:
Code: Select all
undefined reference to `__imp__JNI_GetCreatedJavaVMs@12'
undefined reference to `__imp__JNI_CreateJavaVM@12'
collect2: ld returned 1 exit status
when i use -I..../jdk/include/linux, compiling and linking works just fine.
linux/jni_md.h
Code: Select all
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT
#define JNIIMPORT
#define JNICALL
typedef int jint;
#ifdef _LP64 /* 64-bit Solaris */
typedef long jlong;
#else
typedef long long jlong;
#endif
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */
win32/jni_md.h
Code: Select all
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
typedef long jint;
typedef __int64 jlong;
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */
both these things are about long, and .. shouldn't have to do with floating point stuff, but its the closest i could find.
2nd issue solved:
instead of -ljvm i just appended ...../jdk/lib/jvm.lib at the end of the linking command, and it linked successfully.
thought the FPUCW issue remains.
Posted: 14 Oct 2007, 13:53
by Kloot
Regarding #1, Spring does not use longs*
(or long longs), as their sizes are platform-
dependant. Removing the typedef shouldn't
have any ill effects.
*e: actually, there are a few in the UDP code
and other places, but no __int64's.
Posted: 14 Oct 2007, 15:30
by hoijui
thanks Kloot
something not that important right now but...
if it all works once, how would i integrate it into the global spring compile. i mean that thing with scons, which builds spring.exe and all the AIs automatically. it somehow tries to build JAI too, when i have the folder under AI/Global, but i don't know how... does it just look for all the *.c* and *.h* files? or for makefiles?
Posted: 14 Oct 2007, 16:05
by imbaczek
you'll need to look around rts\build\scons\ dir.
Posted: 14 Oct 2007, 20:34
by Tobi
hoijui wrote:something not that important right now but...
if it all works once, how would i integrate it into the global spring compile. i mean that thing with scons, which builds spring.exe and all the AIs automatically. it somehow tries to build JAI too, when i have the folder under AI/Global, but i don't know how... does it just look for all the *.c* and *.h* files? or for makefiles?
In AI/Global it considers every subdirectory an AI (unless explicitly excluded in SConstruct).
In every AI it just compiles all *.c and *.cpp files (in subdirectories of the AI directory too).
Posted: 14 Oct 2007, 21:01
by hoijui
..ahh.. and why can't it find my .h files?
do they have to be in the root of my ai folder?
Posted: 14 Oct 2007, 21:17
by Tobi
I suppose it only adds AI/Global/JAI as include path to the compiler so you'd need to put the relative path to them from there in the #include directives.
Posted: 14 Oct 2007, 22:58
by hoijui
id doesn't even do that, i had to use the relative path to the .h file in the include statement (relative to the file including the .h file).
now i have to find out how i'll get it to use/find jvm.lib, guess i'll put it into mingwlibs/lib.
but am finished for today, will go on tomorrow.
Posted: 16 Oct 2007, 14:07
by hoijui
trying to get it to use jvm.lib still...
i guess i have to put jvm.lib somewhere under mingwlibs, and then specify something in rts/build/scons/config.py
Code: Select all
def CheckHeadersAndLibraries(env, conf)
is that right?
when linking in my makefile, i use jvm.lib like this (shortened):
which works.
Zwischenbericht (von der Front) / intermediate(?) report
Posted: 19 Oct 2007, 12:25
by hoijui
a short report to let you know where i am.
1. i still get the FPUCW sync error.
what i am trying to do:
compile a small stub-dll with a class implementing IGlobalAI which forwards all calls to Java through the JNI Invocation API.
so the calls get forwarded to a java class called JGlobalAI.
this class will call back to native code, to request unit information for example through JNI.
to release me of writing lots of wrapper classes, i use swig to generate the C++ to Java code, and also for the Java to C++ code.
SWIG is meant to be used like this:
script language(Java) calls native library(C++) native code then possibly calls back to the scripting language.
what i am trying to do here, is the opposite way: native code invokes JVM and calls java methods; java methods possibly call back to native code.
so what i have to do is create a JVM by hand (writing JNI code myself to create it), then create a java class and register it with the C++ stub created by swig.
the problem now is, that the Java class can not find the native code.
i assumed that my C++ JNI exported methods are available in Java when i create the JVM from this very dll, but it somehow seems not to be the case. it neither works when i explicitly load my JAI.dll from the java code.
if i understood it correctly, the same problem occurred in the C# AI interface. where the C# code had to call the C++ code, and it didnt work the other way around.
possibly i will end up doing the same.
who did the C# interface again? :/
how did you do it?
i will try to write a minimal test scenario, where i start a JVM from native code, call a Java method, and let java call back into native code.
has anyone done something like that already?
Posted: 19 Oct 2007, 12:35
by DJ
Hugh Perkins did the C# interface, send him a PM and he might be able to help you.
Posted: 19 Oct 2007, 14:02
by hoijui
thanks DJ

i wrote the small test scenario, and it really seems nto to be possible the way i wanted.
i create a JVM from native code, call a java method from native code (works fine till here), and then let that java method call a native method, which fials with an UnsatisfiedLinkError
Posted: 19 Oct 2007, 14:49
by hoijui
... it does work!
what is needed is a
Code: Select all
System.loadLibrary("LibraryName");
in the Java File.
though i did this in JAI too, it didn't work there... maybe i did something wrong again there. looking into that again now.
Posted: 19 Oct 2007, 18:04
by hoijui
i was/am doing a loadLibrary("JAI") in java, and it successfully loads the library, but i still get the UnsatisfiedLinkError.
i checked with an utility, and JAI.dll is exporting the method that java requests (swig_module_init).
i also looked into the FPUCW sync thing again, but neither got further there.
whole day for nothing -> starts to suck
this project would need a native expert, not someone like me who knows the java world only, though such a person doesn´t need a java interface ...
i looked at JVM arguments, but there is nothing to change the precision control of the FPU.
i hope someone of you gets an idea once, so i can go on, i won't try it myself anymore, making me to pissed off (spending nearly 2 weeks already, just fiddling around with compile arguments, linking stuff, swig parameters and instructions)
Posted: 19 Oct 2007, 20:15
by AF
System.loadbirary attempts to load a native library using JNI.
You cant just make ordinary API calls using JNI you have to write JNI functions in the C++ specifically for JNI using a certain format and taking java defined variable types. Pass an IGlobalAI* and it'll come out as an integer on the java end.
This is why your getting unsatisfied link errors.
declare a java class filled with methods flagged as native and then run javah on the class file to get a set of C function declarations. Fill in the variable names of the parameters and add implementations. Then you'll hava a java -> C/C++ JNI setup.
imo using swig is not the best idea. Its not hard or complicated to use JNI, it just requires a little reading to get through it.
Creating a java vm and using similar mechanisms to spawn a jobject variable of type "MyJavaAI" then passing constructed objects to pre-specified methods shouldnt be hard.
As for fpu, the java VM does indeed mess with the fpu registers. Java floating point numbers work at 64bit precision regardless of the operating system, e.g. linux at 80bit precision. If it didnt do that then java programming would have a lot of holes in its calculations.
Posted: 19 Oct 2007, 22:27
by hoijui
well... thanks AF, but i knew all this

i used JNI before (in both ways, Java->native and native->Java), i know how it works.
as SWIG is just generating code that uses JNI, it is the same like writing JNI by hand.
swig creates a Java class with native functions, then generates a header file for it, and then provides the implementations ina a .cxx file, -> the same one would do by hand.
i just though it would be nice to not have to change the JAI code when the Spring code changes, but instead just run swig.
i dont know if it were that simple to do by hand. thinking on object lifetime management and references of Native objects stored in the Java side or vise versa.
but yeah...
if it wont work with SWIG, one still could use the SWIG generated stuff as a base, and modify it by hand till it works.
the 2 main problems there are right now dont have to do with JNI and FPU, nothing with SWIG as i see it.
i possibly would be able ot solve the problem with JNI somehow, but most likely not the FPU thing.
so at least till someone can help me there, i'll pause the project.
,,tough if you want to go on... i'll send you the latest version of what i have if you want, or just start from scratch.
Posted: 20 Oct 2007, 10:30
by Agon
Good to see, that a new language for the AI is in developing.
But I don't really like Java

.
Why, not making a mono interface with java inside?
You would support more than one language.
http://www.mono-project.com/Java
pause
Posted: 02 Jan 2008, 15:18
by hoijui
i just had a short chat with tobi in the lobby, and he helped me solve a problem i had (yes, i begann working on JAI agian). this time i tryed to do it by hand, as described by AF above. it should theoretically not make a difference, but well...
with the help of tobe and streflop, i got ridd of the sync error messages as follows:
each method call from C/C++ to java gets sourounded like this:
Code: Select all
streflop_init<streflop::Double>();
jniEnv->CallVoidMethod(javaAiInst, method_id);
streflop_init<streflop::Simple>();
i guess the init after the method call would be enough for its own, as java will set the FPU as it wants it anyway. what do you think, should i leave it like this or remove the streflop_init<streflop::Double>(); ?
beside this, i am using JNA at the moment for calling back into C from Java. this also works already. so.. all main technical problems seem to be solved (for the moment). i also wrote the wrappers for all the methods in the GlobalAICallback and AICheat callback already, but i also need java wrappers for all the structs like UnitDef, Command and so on. After that, i guess i will be having some pointer issues (some beeing removed to early, some too late or so). and then some cleanup... and it may be usable.
the problem is: this is my last day here, tomorow early morning i'll leave for half a year, in which i wont have access to a computer regularly. so i will go on when i come, in the beginning of july.
about mono:
i said it in a private message to Agon already:
i am not interested in mono, and when workign with Java and C, i at least have a good idea of one of the parts, which is annoying and frustrating enough already (cause i dont feel at home in the C world, with all the flags and defines and such)
so maybe in the version that comes after 0.76 we'll see JAI available

i hope so!
Re: Java AI Interface for Spring
Posted: 02 Jan 2008, 22:31
by Tobi
I think you can indeed leave away the streflop call before the java method.
Sorry I didn't take a look at the code myself btw, really didn't have time for it between all other things, but I should have at least said that I guess..
Re:
Posted: 26 Jan 2008, 16:22
by McLoud
Agon wrote:Good to see, that a new language for the Why, not making a mono interface with java inside?
Because is hard to build the native <-> CLR bridge. Good luck with that.
Agon wrote:Good to see, that a new language for the You would support more than one language.
The JVM supports more than 200 languages. Java is just the first class citizen.