Java Unitsync
Moderator: Moderators
Java Unitsync
Has any one got an up to date binding of the unitsync library for java?
Re: Java Unitsync
the java bindings are deprecated, you should just use JNA.
a tip: use JNAErator to generate the Java stuff to interface to unitsync through JNA:
http://code.google.com/p/jnaerator/
a tip: use JNAErator to generate the Java stuff to interface to unitsync through JNA:
http://code.google.com/p/jnaerator/
Re: Java Unitsync
Sorry let me rephrase, has anyone got a working Java UnitSync class that uses JNA?
If not Ill look into generating one myself.
Also I tried using something else you posted hoi, unitsyncJNAWrapp.zip, it was ages ago though. It worked except I get errors on some functions like
http://springrts.com/phpbb/viewtopic.ph ... nc&start=0
If not Ill look into generating one myself.
Also I tried using something else you posted hoi, unitsyncJNAWrapp.zip, it was ages ago though. It worked except I get errors on some functions like
Code: Select all
public byte[] GetMinimap(String filename, int miplevel);
Exception in thread "main" java.lang.IllegalArgumentException: Unsupported return type class [B in function GetMinimap
Re: Java Unitsync
I used JNAerator to generate a file. It worked but certain functions like GetMinimap return an int. I presume this int is some kind of pointer but how do i access the data?
The code is @ http://pastebin.com/f5c9df95f because these forums think im attacking them by attaching the file.
The code is @ http://pastebin.com/f5c9df95f because these forums think im attacking them by attaching the file.
Re: Java Unitsync
try replacing the "int" with "byte[]" in the generated java file. I guess you were right with the int beeing a pointer, but JNA supports array mapping (see their page for more info, they support really a lot). maybe there is even a JNAerator option to do this automatically.
Re: Java Unitsync
when changing it to byte[] i just get an error
Code: Select all
java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at java.lang.reflect.Array.getLength(Native Method)
at com.sun.jna.Structure$FFIType.<init>(Structure.java:1194)
at com.sun.jna.Structure$FFIType.get(Structure.java:1245)
at com.sun.jna.Structure$FFIType.get(Structure.java:1212)
at com.sun.jna.Native.register(Native.java:1249)
at com.sun.jna.Native.register(Native.java:1003)
at org.petah.spring.UnitSync2.<clinit>(UnitSync2.java:24)
Could not find the main class: org.petah.spring.UnitSync2. Program will exit.
Exception in thread "main" Java Result: 1
Re: Java Unitsync
The getminimap callout in itself is a horrid callout in my opinion and needs replacing with somethign a little more friendly. Other API bindings could simply pass a filepath instead and have it output a jpeg for them, why cant we do the same here without faffing around if we're using anything that doesnt compile natively into x86?
Re: Java Unitsync
for anyone possibly interested. the solution was to remove all occurences of the EXPORT macro from the native source file before feeding it into JNAerator.
Re: Java Unitsync
Ive ran into a problem when calling GetMapInfo, it causes the JVM to crash probably because of an error occurring the the c code.
It seems almost random as it occurs on many different maps on different runs. However its normally within the first 5 or so maps scanned.
Here is the console output from the crash
The source for the UnitSync class and NativeUnitSync class is here
http://pastebin.com/fa727c1e and http://pastebin.com/m39e833c6
The JVM error log file is here http://pastebin.com/f354de4ce
It seems almost random as it occurs on many different maps on different runs. However its normally within the first 5 or so maps scanned.
Here is the console output from the crash
Code: Select all
run:
LogOutput initialized.
Spring 0.80.4.0 (0.80.4-0-ga0534a8{@}-cmake-mingw32)
Available log subsystems: VFS-detail, VFS, ArchiveScanner, unitsync
Enabled log subsystems: unitsync
Enable or disable log subsystems using the LogSubsystems configuration key
or the SPRING_LOG_SUBSYSTEMS environment variable (both comma separated).
unitsync: loaded, 0.80.4.0 (0.80.4-0-ga0534a8{@}-cmake-mingw32)
default config file: C:\Users\Petah\AppData\Local\springsettings.cfg
Using read-write data directory: D:\Games\Spring\
Using read-only data directory: C:\Users\Petah\Documents\My Games\Spring\
Using read-only data directory: C:\Users\Petah\Documents\Spring\
Using read-only data directory: C:\ProgramData\Spring\
Scanning: C:\ProgramData\Spring\maps
Scanning: C:\ProgramData\Spring\base
Scanning: C:\ProgramData\Spring\mods
Scanning: C:\ProgramData\Spring\packages
Scanning: C:\Users\Petah\Documents\Spring\maps
Scanning: C:\Users\Petah\Documents\Spring\base
Scanning: C:\Users\Petah\Documents\Spring\mods
Scanning: C:\Users\Petah\Documents\Spring\packages
Scanning: C:\Users\Petah\Documents\My Games\Spring\maps
Scanning: C:\Users\Petah\Documents\My Games\Spring\base
Scanning: C:\Users\Petah\Documents\My Games\Spring\mods
Scanning: C:\Users\Petah\Documents\My Games\Spring\packages
Scanning: D:\Games\Spring\maps
Error opening D:\Games\Spring\maps\AATA-RumblingForest.sd7: Unknown error
Error opening D:\Games\Spring\maps\Foothills-v07.sdz
Error opening D:\Games\Spring\maps\High_and_Low_Redux.sd7: Unknown error
Error opening D:\Games\Spring\maps\Relics-V2.sd7: Unknown error
Scanning: D:\Games\Spring\base
Scanning: D:\Games\Spring\mods
Scanning: D:\Games\Spring\packages
unitsync: initialized, 0.80.4.0 (0.80.4-0-ga0534a8{@}-cmake-mingw32)
unitsync: joining
275
------------------------------------------
1944_BocageSmall.smf
-1870956879
unitsync: get map info: 1944_BocageSmall.smf
unitsync: startpos: 600, 600
unitsync: startpos: 3600, 3600
unitsync: startpos: 3600, 600
unitsync: startpos: 600, 3600
unitsync: startpos: 2000, 600
unitsync: startpos: 2000, 3600
#
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x76e8814c, pid=3372, tid=8484
#
# Java VM: Java HotSpot(TM) Client VM (11.3-b02 mixed mode, sharing windows-x86)
# Problematic frame:
# C [ntdll.dll+0x6814c]
#
# An error report file with more information is saved as:
# D:\Games\Spring\hs_err_pid3372.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Java Result: 1
BUILD SUCCESSFUL (total time: 7 seconds)
http://pastebin.com/fa727c1e and http://pastebin.com/m39e833c6
The JVM error log file is here http://pastebin.com/f354de4ce
Re: Java Unitsync
The best guess i have is that this comes from you not using the StdCalling convention.
i am new to this too, but my guess is, the problem lies in the first few lines in the NativeUnitSync class. You are using DEFAULT_OPTIONS, but i think you will have to manually specify StdCalling convention there, somehow. Also, when you call the Native.register() method, i think you should pass it the above created NativeLibrary instance, and not the name.
I am working on a nearly equal issue with the Java AI Interface callback
so maybe we can help each other when doing progress.
i am new to this too, but my guess is, the problem lies in the first few lines in the NativeUnitSync class. You are using DEFAULT_OPTIONS, but i think you will have to manually specify StdCalling convention there, somehow. Also, when you call the Native.register() method, i think you should pass it the above created NativeLibrary instance, and not the name.
I am working on a nearly equal issue with the Java AI Interface callback

Re: Java Unitsync
the way i am doing it now:
compiles and runs, though as i strangely had no problems before...
apart of the ugly way to find out that we are running win32, this seems like the right way to go.
Code: Select all
static {
java.util.Map<String, Integer> myNativeLibOptions = new java.util.HashMap<String, Integer>();
if (isWin32()) {
myNativeLibOptions.put(Library.OPTION_CALLING_CONVENTION, com.sun.jna.win32.StdCallLibrary.STDCALL_CONVENTION);
}
NativeLibrary myNativeLib = NativeLibrary.getInstance("AIInterface", myNativeLibOptions);
Native.register(myNativeLib);
}
public static final boolean isWin32() {
final String osName = System.getProperty("os.name", "UNKNOWN");
final boolean isWindows = osName.matches("[Ww]in");
final String arch = System.getProperty("sun.arch.data.model", "32");
final boolean is32bit = arch.equals("32");
//final String arch = System.getProperty("os.arch", "foobar");
//final boolean is32bit = arch.equals("x86");
return (isWindows && is32bit);
}
apart of the ugly way to find out that we are running win32, this seems like the right way to go.
Re: Java Unitsync
In case anyone is still interested, and hasn't figured it out yet :)
The reason for GetMapInfo to crash is that the passed MapInfo object has two string fields, which need to be filled already :)
So:
These two classes work for me :)
The reason for GetMapInfo to crash is that the passed MapInfo object has two string fields, which need to be filled already :)
So:
Code: Select all
public String description= new String(new char[255+1]); // /< Description (max 255 chars)
Code: Select all
public static class StartPos extends Structure {
public int x; ///< X component // 4
public int z; ///< Z component // 4
}
public static class MapInfo extends Structure {
public String description= new String(new char[255+1]); // /< Description (max 255 chars) //4
public int tidalStrength; // /< Tidal strength //4 - 8
public int gravity; // /< Gravity // 4 - 12
public float maxMetal; // /< Metal scale factor // 4 - 16
public int extractorRadius; // /< Extractor radius (of metal extractors) // 4 - 20
public int minWind; // /< Minimum wind speed // 4 - 24
public int maxWind; // /< Maximum wind speed // 4 - 28
// 0.61b1+
public int width; // /< Width of the map // 4 - 32
public int height; // /< Height of the map // 4 - 36
public int posCount; // /< Number of defined start positions // 4 - 40
public StartPos[] positions = (StartPos[]) new StartPos().toArray(16); // 2 * 4 * 16 = 128 0 168
// new StartPos.ByValue[16]; ///< Start positions defined by the map (max 16)
// VERSION>=1
public String author = new String(new char[200+1]); // /< Creator of the map (max 200 chars) // 4 - 172
}
Re: Java Unitsync
Would new String("") or even new String("-") be less wasteful? If only because there's less memory use, and your no longer inviting potential undefined behaviour via the creation of a new char array whose values are undefined?
Re: Java Unitsync
NO! :)AF wrote:Would new String("") or even new String("-") be less wasteful? If only because there's less memory use, and your no longer inviting potential undefined behaviour via the creation of a new char array whose values are undefined?
The point is that the unitsync code needs a pre-allocated byte array to dump it's string in.
That's why they added those //max 200 comments. That's the length of the array that's needed to contain anything they may put in there :)
If you use a empty string, unallocated memory is gonna be written in, and you get all kinds of pain XD
Ohyeah..
In java, anything created has default values :)
creating a char[100] array means you create a char array with 100 '0' values :)
Re: Java Unitsync
But does this not then get interned by the VM? String is a special case object in java hmmm
Re: Java Unitsync
JNA makes char arrays out of the String.AF wrote:But does this not then get interned by the VM? String is a special case object in java hmmm
JNA can't telepathically know how big those arrays need to be :)
So you use a String of a certain size, to let it know how big to make the array :)
I don't know if it uses the backing array of the String to pass, or creates a newone, I think the lastone.
So your kinda right at wasted space, tho it'll soon be garbish collected.
But there's not really many other ways, and there always needs to be an allocated array to pass to the code, of size 200 :)
Re: Java Unitsync
Ah thanks cranphin ( lols at aegis )