I'm new to JNative and have struggled to find some example code - specifically something using the NativeMemoryBlock class.
PROBLEM:
I am storing a handle that contains a pointer to an object in the JNative class Pointer with the default memory block type which I assume is a HeapMemoryBlock type. The problem is that when Java's garbage collection occurs or when I call System.gc(), the handle is no longer valid. I assume it's because the jvm heap is being rearranged and the pointer is no longer valid. My code is below.
WHAT I THINK I NEED TO DO:
I think I should be using the MemoryBlockFactory to make a NativeMemoryBlock object to pass to the JNative Pointer object instead of a HeapMemoryBlock (But I don't know how to use MemoryBlockFactory.setPreferredMemoryType() correctly). I would like to create a NativeMemoryBlock, but it seems like the only way to do so would be to have a non-java program to allocate native memory and then have that non-java program pass my program the pointer so that my NativeMemoryBlock constructor can use that address. Is this the only way to do it or can I use Java or JNative to request a NativeMemoryBlock? In other words, is it possible to create a valid NativeMemoryBlock within my java program that uses JNative? If so, example code would help.
PSEUDOCODE THAT DOESNT WORK:
handlePtr = new Pointer(MemoryBlockFactory.createMemoryBlock(SIZE_OF_POINTER));
Interface.openConnection(handlePtr); //handlePtr is a JNative Pointer objct that contains provides a place to store the handle
System.gc(); //without this gc(), the connection is valid until a point in time when java automatically gc's
Interface.useConnection(handlePtr); //this will not work since the handlePtr is no longer valid since it was gc'd
Any help would be greatly appreciated.
Thanks,
jb
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Why don't you just store the Pointer Object in a "global" List or Map or something like this _before_ you call System.gc()? As the object remains referenced it shouldn't get GCed.
Thubby
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I always have a valid reference to the Pointer object even after gc() calls. It's the address that the Pointer object points to that is invalid after the gc(). I need this handle to have a fixed address so that when gc() is called the Pointer object still refers to a valid handle. As it is now, MemoryBlockFactory.createMemoryBlock() returns the address of some memory that my Pointer object can use. However, that memory is on the jvm heap ( I believe ). It really needs to be outside of the heap in order to remained at a fixed location after the gc().
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
No, what I mean is to store the Pointer-Object somewhere in a global map so that GC won't call Pointer's finalize() method - which disposes the native memory. Please have a look at the Pointer class - finalize().
As I don't know too much about JNative's native memory handling, I cannot tell you if a GC "re-arranges" the heap and invalidates the pointer address optained by JNative (personally I don't think so). Mabye Marc can help us here.
Thubby
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It turns out that calling System.gc() is not actually changing the address of the pointer or the address the pointer points to. Calling
System.out.println("getHandlePtr: " + myConnection.getHandlePtr()); and
System.out.println("getHandlePtrVal: " + myConnection.getHandlePtr().getAsInt(0));
before and after the System.gc() return the same value. Though for some reason it seems to crash A LOT right after the gc() call which is suspicious and interesting.
I will have to rethink this one.
I will paste some code and the error message.
The error message contains the phrase: " # Problematic frame:# C 0x032802aa" and when I go to the log file it says the "C" denotes something to do with the native code. Is it possible that the bug is in my third party DLL and not my jnative/java code?
Also, I'm wondering if I'm setting up my parameters types correctly.
Please take a look. My code and error outputs are below.
Thanks again,
jb
CODE:
/*
int write (HANDLE handle, int start, int number, unsigned char *values) , where start = starting output, number = quantity of outputs to write, value = desired output state
*/
public static void write(int handleAddress, int start, int number, String values) {
int retVal = -1;
try {
JNative fs = new JNative("TheDLL.dll", "write");
fs.setRetVal(Type.INT);
fs.setParameter(0, handleAddress);
fs.setParameter(1, start);
fs.setParameter(2, number);
fs.setParameter(3, values);
fs.invoke();
} catch (NativeException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
}
}
ERROR:
#
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x032802aa, pid=788, tid=500
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b06 mixed mode, sharing)
# Problematic frame:
# C 0x032802aa
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x03011c00): JavaThread "AWT-EventQueue-0" [_thread_in_native, id=500]
Other Threads:
0x02a44000 VMThread [id=4012]
0x02a67000 WatcherThread [id=3572]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
Heap
def new generation total 960K, used 84K [0x22960000, 0x22a60000, 0x22e40000)
eden space 896K, 6% used [0x22960000, 0x2296e630, 0x22a40000)
from space 64K, 42% used [0x22a40000, 0x22a46b90, 0x22a50000)
to space 64K, 0% used [0x22a50000, 0x22a50000, 0x22a60000)
tenured generation total 4096K, used 960K [0x22e40000, 0x23240000, 0x26960000)
the space 4096K, 23% used [0x22e40000, 0x22f30300, 0x22f30400, 0x23240000)
compacting perm gen total 12288K, used 1056K [0x26960000, 0x27560000, 0x2a960000)
the space 12288K, 8% used [0x26960000, 0x26a68000, 0x26a68000, 0x27560000)
ro space 8192K, 66% used [0x2a960000, 0x2aead978, 0x2aeada00, 0x2b160000)
rw space 12288K, 52% used [0x2b160000, 0x2b7a9cb8, 0x2b7a9e00, 0x2bd60000)
You'll notice that the c++ function returns an int. My wrapper function just doesn't use that int/throws it away so that's why my function returns void.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
/*
int write (HANDLE handle, int start, int number, unsigned char *values) , where start = starting output, number = quantity of outputs to write, value = desired output state
*/
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I rewrote some parts of JNative which could maybe solve your problems - but this is not yet official, so you have to download the source code from CVS.
Thubby
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried your two suggestions and they didn't work. I might have downloaded the wrong version.
I have tried both changing that string to a pointer as well as downloading FROM THE CVS WEB BROWSER the file /JNative/bin/java/bin/JNative.jar revision 1.6 beta 2. Is that the correct file? It says its age is 2 years so I didn't know if that was the most recent one. I also couldn't download using anonymous cvs access because it timed out. It might be a firewall issue.
Should I be downloading just the Jnative.jar or do I need to get the source and compile it myself?
Thanks for your help so far.
Jb
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have learned that after the garbage collection the native memory that my Pointer references is null - or at least I think it is. Except for the first 4 bytes, everything else has been zeroed out. Why would that be? The java garbage collection should not be able to affect any memory outside the jvm's heap.
One other thing that's odd is that for the first 15 or so seconds after the garbage collection occurs, if I try to use the handle, java gives an EXCEPTION_ACCESS_VIOLATION. BUT if I don't use the handle until after those 15 seconds or so, I can look at the memory and see that it has been reinitialized (or so I think).
Could you please tell me more about why you thought that placing the handle (which is a JNative Pointer object) into the global map would prevent it from being affected by Java's garbage collector?
I tried making a global HashMap and adding my handlePtr into it, but it still seemed to nullify my native memory after the garbage collection.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So I allocate in JNative 4 bytes for the handle which is a pointer. Do I need to allocate more bytes for the object that that handle actually represents? I think my library is doing that for me.
Also, what's the difference between a globalmemoryblock and a nativememoryblock and when would I need to create those objects?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
actually I'm fairly sure I didn't download the latest version from the cvs web browser because "Pointer buf = Pointer.createPointerFromString(values);" didn't work.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thubby was close, and I thank him greatly for his patience and tips. Though my Pointers did not need to have a global reference, my **JNative** object did. When write() was called, fs is a local variable, and its reference is lost. When its reference is lost, the gc() will eventually call finalize - which I believe calls dispose(). Dispose() makes it so I can no longer use the dll. I needed a reference for my jnative object.
Thubby, thanks again.
jb
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
No you have to download the complete source code (no jar or whatever) from the CVS. Not only one file but the complete source.
Your problem is (in my opinion) exactly what I fixed in CVS. dispose() is deprecated and no longer used in the latest version and I completely rewrote the function-pointer caching. Now at least one instance of each dll is kept in memory so that GC cannot dispose it. Removing dispose() from your implementation might cause a memory-leak while fixing your problems though.
I already found the bug and I got it working with the released 1.3.2, but I will try to find some time to run it with the latest JNative.jar and see how it goes.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi all,
I'm new to JNative and have struggled to find some example code - specifically something using the NativeMemoryBlock class.
PROBLEM:
I am storing a handle that contains a pointer to an object in the JNative class Pointer with the default memory block type which I assume is a HeapMemoryBlock type. The problem is that when Java's garbage collection occurs or when I call System.gc(), the handle is no longer valid. I assume it's because the jvm heap is being rearranged and the pointer is no longer valid. My code is below.
WHAT I THINK I NEED TO DO:
I think I should be using the MemoryBlockFactory to make a NativeMemoryBlock object to pass to the JNative Pointer object instead of a HeapMemoryBlock (But I don't know how to use MemoryBlockFactory.setPreferredMemoryType() correctly). I would like to create a NativeMemoryBlock, but it seems like the only way to do so would be to have a non-java program to allocate native memory and then have that non-java program pass my program the pointer so that my NativeMemoryBlock constructor can use that address. Is this the only way to do it or can I use Java or JNative to request a NativeMemoryBlock? In other words, is it possible to create a valid NativeMemoryBlock within my java program that uses JNative? If so, example code would help.
PSEUDOCODE THAT DOESNT WORK:
handlePtr = new Pointer(MemoryBlockFactory.createMemoryBlock(SIZE_OF_POINTER));
Interface.openConnection(handlePtr); //handlePtr is a JNative Pointer objct that contains provides a place to store the handle
System.gc(); //without this gc(), the connection is valid until a point in time when java automatically gc's
Interface.useConnection(handlePtr); //this will not work since the handlePtr is no longer valid since it was gc'd
Any help would be greatly appreciated.
Thanks,
jb
Why don't you just store the Pointer Object in a "global" List or Map or something like this _before_ you call System.gc()? As the object remains referenced it shouldn't get GCed.
Thubby
I always have a valid reference to the Pointer object even after gc() calls. It's the address that the Pointer object points to that is invalid after the gc(). I need this handle to have a fixed address so that when gc() is called the Pointer object still refers to a valid handle. As it is now, MemoryBlockFactory.createMemoryBlock() returns the address of some memory that my Pointer object can use. However, that memory is on the jvm heap ( I believe ). It really needs to be outside of the heap in order to remained at a fixed location after the gc().
No, what I mean is to store the Pointer-Object somewhere in a global map so that GC won't call Pointer's finalize() method - which disposes the native memory. Please have a look at the Pointer class - finalize().
As I don't know too much about JNative's native memory handling, I cannot tell you if a GC "re-arranges" the heap and invalidates the pointer address optained by JNative (personally I don't think so). Mabye Marc can help us here.
Thubby
When you use the term "global map" do you mean an associative array with a key/value pair?
Also, thanks for the quick response. :)
Hey Thubby,
It turns out that calling System.gc() is not actually changing the address of the pointer or the address the pointer points to. Calling
System.out.println("getHandlePtr: " + myConnection.getHandlePtr()); and
System.out.println("getHandlePtrVal: " + myConnection.getHandlePtr().getAsInt(0));
before and after the System.gc() return the same value. Though for some reason it seems to crash A LOT right after the gc() call which is suspicious and interesting.
I will have to rethink this one.
I will paste some code and the error message.
The error message contains the phrase: " # Problematic frame:# C 0x032802aa" and when I go to the log file it says the "C" denotes something to do with the native code. Is it possible that the bug is in my third party DLL and not my jnative/java code?
Also, I'm wondering if I'm setting up my parameters types correctly.
Please take a look. My code and error outputs are below.
Thanks again,
jb
CODE:
/*
int write (HANDLE handle, int start, int number, unsigned char *values) , where start = starting output, number = quantity of outputs to write, value = desired output state
*/
public static void write(int handleAddress, int start, int number, String values) {
int retVal = -1;
try {
JNative fs = new JNative("TheDLL.dll", "write");
fs.setRetVal(Type.INT);
fs.setParameter(0, handleAddress);
fs.setParameter(1, start);
fs.setParameter(2, number);
fs.setParameter(3, values);
fs.invoke();
} catch (NativeException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
}
}
ERROR:
#
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x032802aa, pid=788, tid=500
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b06 mixed mode, sharing)
# Problematic frame:
# C 0x032802aa
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x03011c00): JavaThread "AWT-EventQueue-0" [_thread_in_native, id=500]
siginfo: ExceptionCode=0xc0000005, writing address 0x00000000
Registers:
EAX=0x03280288, EBX=0x00000000, ECX=0x03283ef8, EDX=0x032802a8
ESP=0x02faf044, EBP=0x02fbf298, ESI=0x03280288, EDI=0x00000000
EIP=0x032802aa, EFLAGS=0x00010246
Top of Stack: (sp=0x02faf044)
0x02faf044: 03207020 00000000 02ae36e0 02ae3acc
0x02faf054: 002901c8 03011e78 03011c00 00000000
0x02faf064: 03011c00 26a45dc0 6d8c60a2 00000006
0x02faf074: 26a3ebe8 00000036 02faf10c 6d90337a
0x02faf084: 26a3ebe8 00000036 26a41fb8 00000077
0x02faf094: 26a3ebe8 6d91bd14 03011e78 6d888186
0x02faf0a4: 03011c00 03011e70 03011c00 03011e6c
0x02faf0b4: 02faf0a8 6d91cf1c 02fbfa64 6da35f8a
Instructions: (pc=0x032802aa)
0x0328029a: 28 03 98 02 28 03 a0 02 28 03 a0 02 28 03 a8 02
0x032802aa: 28 03 a8 02 28 03 b0 02 28 03 b0 02 28 03 b8 02
Stack: [0x02f70000,0x02fc0000), sp=0x02faf044, free space=252k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C 0x032802aa
j org.xvolks.jnative.JNative.nInvoke(I)V+0
j org.xvolks.jnative.JNative.invoke()V+9
j videoviewer.SeaLevelHelperInterface.SM_WriteDigitalOutputs(IIILjava/lang/String;)V+62
j videoviewer.Connection.SM_WriteDigitalOutputs(Ljava/lang/String;)V+44
j videoviewer.VideoViewer$2.actionPerformed(Ljava/awt/event/ActionEvent;)V+97
j javax.swing.AbstractButton.fireActionPerformed(Ljava/awt/event/ActionEvent;)V+84
j javax.swing.AbstractButton$Handler.actionPerformed(Ljava/awt/event/ActionEvent;)V+5
j javax.swing.DefaultButtonModel.fireActionPerformed(Ljava/awt/event/ActionEvent;)V+35
j javax.swing.DefaultButtonModel.setPressed(Z)V+117
j javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Ljava/awt/event/MouseEvent;)V+35
j java.awt.Component.processMouseEvent(Ljava/awt/event/MouseEvent;)V+64
j javax.swing.JComponent.processMouseEvent(Ljava/awt/event/MouseEvent;)V+23
j java.awt.Component.processEvent(Ljava/awt/AWTEvent;)V+81
j java.awt.Container.processEvent(Ljava/awt/AWTEvent;)V+18
j java.awt.Component.dispatchEventImpl(Ljava/awt/AWTEvent;)V+562
j java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V+42
J java.awt.LightweightDispatcher.retargetMouseEvent(Ljava/awt/Component;ILjava/awt/event/MouseEvent;)V
j java.awt.LightweightDispatcher.processMouseEvent(Ljava/awt/event/MouseEvent;)Z+139
j java.awt.LightweightDispatcher.dispatchEvent(Ljava/awt/AWTEvent;)Z+50
j java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V+12
j java.awt.Window.dispatchEventImpl(Ljava/awt/AWTEvent;)V+19
j java.awt.Component.dispatchEvent(Ljava/awt/AWTEvent;)V+2
j java.awt.EventQueue.dispatchEvent(Ljava/awt/AWTEvent;)V+46
J java.awt.EventDispatchThread.pumpOneEventForFilters(I)Z
j java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V+30
j java.awt.EventDispatchThread.pumpEventsForHierarchy(ILjava/awt/Conditional;Ljava/awt/Component;)V+11
j java.awt.EventDispatchThread.pumpEvents(ILjava/awt/Conditional;)V+4
j java.awt.EventDispatchThread.pumpEvents(Ljava/awt/Conditional;)V+3
j java.awt.EventDispatchThread.run()V+9
v ~StubRoutines::call_stub
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.xvolks.jnative.JNative.nInvoke(I)V+0
j org.xvolks.jnative.JNative.invoke()V+9
j videoviewer.SeaLevelHelperInterface.SM_WriteDigitalOutputs(IIILjava/lang/String;)V+62
j videoviewer.Connection.SM_WriteDigitalOutputs(Ljava/lang/String;)V+44
j videoviewer.VideoViewer$2.actionPerformed(Ljava/awt/event/ActionEvent;)V+97
j javax.swing.AbstractButton.fireActionPerformed(Ljava/awt/event/ActionEvent;)V+84
j javax.swing.AbstractButton$Handler.actionPerformed(Ljava/awt/event/ActionEvent;)V+5
j javax.swing.DefaultButtonModel.fireActionPerformed(Ljava/awt/event/ActionEvent;)V+35
j javax.swing.DefaultButtonModel.setPressed(Z)V+117
j javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Ljava/awt/event/MouseEvent;)V+35
j java.awt.Component.processMouseEvent(Ljava/awt/event/MouseEvent;)V+64
j javax.swing.JComponent.processMouseEvent(Ljava/awt/event/MouseEvent;)V+23
j java.awt.Component.processEvent(Ljava/awt/AWTEvent;)V+81
j java.awt.Container.processEvent(Ljava/awt/AWTEvent;)V+18
j java.awt.Component.dispatchEventImpl(Ljava/awt/AWTEvent;)V+562
j java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V+42
J java.awt.LightweightDispatcher.retargetMouseEvent(Ljava/awt/Component;ILjava/awt/event/MouseEvent;)V
j java.awt.LightweightDispatcher.processMouseEvent(Ljava/awt/event/MouseEvent;)Z+139
j java.awt.LightweightDispatcher.dispatchEvent(Ljava/awt/AWTEvent;)Z+50
j java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V+12
j java.awt.Window.dispatchEventImpl(Ljava/awt/AWTEvent;)V+19
j java.awt.Component.dispatchEvent(Ljava/awt/AWTEvent;)V+2
j java.awt.EventQueue.dispatchEvent(Ljava/awt/AWTEvent;)V+46
J java.awt.EventDispatchThread.pumpOneEventForFilters(I)Z
j java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V+30
j java.awt.EventDispatchThread.pumpEventsForHierarchy(ILjava/awt/Conditional;Ljava/awt/Component;)V+11
j java.awt.EventDispatchThread.pumpEvents(ILjava/awt/Conditional;)V+4
j java.awt.EventDispatchThread.pumpEvents(Ljava/awt/Conditional;)V+3
j java.awt.EventDispatchThread.run()V+9
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x00296400 JavaThread "DestroyJavaVM" [_thread_blocked, id=2972]
=>0x03011c00 JavaThread "AWT-EventQueue-0" [_thread_in_native, id=500]
0x02ae2400 JavaThread "AWT-Windows" daemon [_thread_in_native, id=588]
0x02ae1800 JavaThread "AWT-Shutdown" [_thread_blocked, id=3488]
0x02a90800 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=3008]
0x02a5cc00 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=1872]
0x02a58000 JavaThread "CompilerThread0" daemon [_thread_blocked, id=3912]
0x02a56c00 JavaThread "Attach Listener" daemon [_thread_blocked, id=3280]
0x02a56000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=3564]
0x02a51800 JavaThread "Finalizer" daemon [_thread_blocked, id=2840]
0x02a4d000 JavaThread "Reference Handler" daemon [_thread_blocked, id=1776]
Other Threads:
0x02a44000 VMThread [id=4012]
0x02a67000 WatcherThread [id=3572]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
Heap
def new generation total 960K, used 84K [0x22960000, 0x22a60000, 0x22e40000)
eden space 896K, 6% used [0x22960000, 0x2296e630, 0x22a40000)
from space 64K, 42% used [0x22a40000, 0x22a46b90, 0x22a50000)
to space 64K, 0% used [0x22a50000, 0x22a50000, 0x22a60000)
tenured generation total 4096K, used 960K [0x22e40000, 0x23240000, 0x26960000)
the space 4096K, 23% used [0x22e40000, 0x22f30300, 0x22f30400, 0x23240000)
compacting perm gen total 12288K, used 1056K [0x26960000, 0x27560000, 0x2a960000)
the space 12288K, 8% used [0x26960000, 0x26a68000, 0x26a68000, 0x27560000)
ro space 8192K, 66% used [0x2a960000, 0x2aead978, 0x2aeada00, 0x2b160000)
rw space 12288K, 52% used [0x2b160000, 0x2b7a9cb8, 0x2b7a9e00, 0x2bd60000)
Dynamic libraries:
0x00400000 - 0x00423000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\java.exe
0x7c900000 - 0x7c9b0000 C:\WINDOWS\system32\ntdll.dll
0x7c800000 - 0x7c8f5000 C:\WINDOWS\system32\kernel32.dll
0x77dd0000 - 0x77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
0x77e70000 - 0x77f02000 C:\WINDOWS\system32\RPCRT4.dll
0x77fe0000 - 0x77ff1000 C:\WINDOWS\system32\Secur32.dll
0x7c340000 - 0x7c396000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\msvcr71.dll
0x6d870000 - 0x6dab9000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\client\jvm.dll
0x7e410000 - 0x7e4a0000 C:\WINDOWS\system32\USER32.dll
0x77f10000 - 0x77f57000 C:\WINDOWS\system32\GDI32.dll
0x76b40000 - 0x76b6d000 C:\WINDOWS\system32\WINMM.dll
0x6d3c0000 - 0x6d3c8000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\hpi.dll
0x76bf0000 - 0x76bfb000 C:\WINDOWS\system32\PSAPI.DLL
0x6d820000 - 0x6d82c000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\verify.dll
0x6d460000 - 0x6d47f000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\java.dll
0x6d860000 - 0x6d86f000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\zip.dll
0x6d0b0000 - 0x6d273000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\awt.dll
0x73000000 - 0x73026000 C:\WINDOWS\system32\WINSPOOL.DRV
0x77c10000 - 0x77c68000 C:\WINDOWS\system32\msvcrt.dll
0x76390000 - 0x763ad000 C:\WINDOWS\system32\IMM32.dll
0x774e0000 - 0x7761d000 C:\WINDOWS\system32\ole32.dll
0x73760000 - 0x737a9000 C:\WINDOWS\system32\ddraw.dll
0x73bc0000 - 0x73bc6000 C:\WINDOWS\system32\DCIMAN32.dll
0x6d360000 - 0x6d3b3000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\fontmanager.dll
0x74720000 - 0x7476b000 C:\WINDOWS\system32\MSCTF.dll
0x7c9c0000 - 0x7d1d6000 C:\WINDOWS\system32\shell32.dll
0x77f60000 - 0x77fd6000 C:\WINDOWS\system32\SHLWAPI.dll
0x773d0000 - 0x774d3000 C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2982_x-ww_ac3f9c03\comctl32.dll
0x5d090000 - 0x5d12a000 C:\WINDOWS\system32\comctl32.dll
0x6d620000 - 0x6d633000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\net.dll
0x71ab0000 - 0x71ac7000 C:\WINDOWS\system32\WS2_32.dll
0x71aa0000 - 0x71aa8000 C:\WINDOWS\system32\WS2HELP.dll
0x6d640000 - 0x6d649000 C:\Program Files\Java\jdk1.6.0_02\jre\bin\nio.dll
0x10000000 - 0x100cd000 C:\Documents and Settings\julian.bui\Desktop\VideoViewer\JNativeCpp.dll
0x76c30000 - 0x76c5e000 C:\WINDOWS\system32\WINTRUST.dll
0x77a80000 - 0x77b14000 C:\WINDOWS\system32\CRYPT32.dll
0x77b20000 - 0x77b32000 C:\WINDOWS\system32\MSASN1.dll
0x76c90000 - 0x76cb8000 C:\WINDOWS\system32\IMAGEHLP.dll
0x03390000 - 0x0339d000 C:\Program Files\Gunze\U-TP\tbhook.dll
0x605d0000 - 0x605d9000 C:\WINDOWS\system32\mslbui.dll
0x77120000 - 0x771ab000 C:\WINDOWS\system32\OLEAUT32.DLL
0x03200000 - 0x03225000 C:\WINDOWS\system32\SeaMAX.dll
0x03230000 - 0x03262000 C:\WINDOWS\system32\FTD2XX.dll
0x77920000 - 0x77a13000 C:\WINDOWS\system32\SETUPAPI.dll
VM Arguments:
java_command: videoviewer.Main
Launcher Type: SUN_STANDARD
Environment Variables:
JAVA_HOME=C:\Program Files\Java\jdk1.6.0_02
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;V:\jltv_dev\JLTV_Projects\Shared_Dlls;C:\Program Files\ATI Technologies\ATI Control Panel;C:\Ca_Appsw;C:\SYSMGT\TNGSD\BIN;C:\Program Files\Java\jdk1.6.0_02\bin;C:\Program Files\TortoiseSVN\bin
USERNAME=julian.bui
OS=Windows_NT
PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 3, GenuineIntel
--------------- S Y S T E M ---------------
OS: Windows XP Build 2600 Service Pack 2
CPU:total 2 (1 cores per cpu, 2 threads per core) family 15 model 4 stepping 3, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ht
Memory: 4k page, physical 1308740k(361664k free), swap 2728876k(1857064k free)
vm_info: Java HotSpot(TM) Client VM (1.6.0_02-b06) for windows-x86, built on Jul 12 2007 01:16:14 by "java_re" with unknown MS VC++:1310
You'll notice that the c++ function returns an int. My wrapper function just doesn't use that int/throws it away so that's why my function returns void.
Also, this method interfaces with a hardware device.
It makes no changes to any of the parameters passed in.
I mean any type of Object that can persistently store an other object (like i.e. ArrayList or HashMap, etc.).
Thubby
Your JNative code looks good, although I cannot tell you for sure as you did not post the native method header.
Did you try the most recent JNative code from CVS? Maybe this is related to this bug: http://sourceforge.net/tracker/index.php?func=detail&aid=2009616&group_id=156421&atid=799718
Could you please download the latest code from CVS and try again?
Thubby
Actually I commented it out in the code I posted:
/*
int write (HANDLE handle, int start, int number, unsigned char *values) , where start = starting output, number = quantity of outputs to write, value = desired output state
*/
And yes, I have JNative 1.3.2
> Actually I commented it out in the code I posted:
Ah sorry, did not see it.
I am not really sure if "unsigned char *values" corresponds to a Java-String, but my C-knowledge is very poor...
> And yes, I have JNative 1.3.2
Yes, but you should try the recent version in CVS - which you can anonymously download like described here: http://sourceforge.net/cvs/?group_id=156421
I rewrote some parts of JNative which could maybe solve your problems - but this is not yet official, so you have to download the source code from CVS.
Thubby
Btw: you only need to download the java part of JNative from CVS...
Thubby
Should I just download this file:
/JNative/bin/java/bin/JNative.jar and replace it with the old one on my computer, or should I download some source and compile it?
I tried your two suggestions and they didn't work. I might have downloaded the wrong version.
I have tried both changing that string to a pointer as well as downloading FROM THE CVS WEB BROWSER the file /JNative/bin/java/bin/JNative.jar revision 1.6 beta 2. Is that the correct file? It says its age is 2 years so I didn't know if that was the most recent one. I also couldn't download using anonymous cvs access because it timed out. It might be a firewall issue.
Should I be downloading just the Jnative.jar or do I need to get the source and compile it myself?
Thanks for your help so far.
Jb
I have learned that after the garbage collection the native memory that my Pointer references is null - or at least I think it is. Except for the first 4 bytes, everything else has been zeroed out. Why would that be? The java garbage collection should not be able to affect any memory outside the jvm's heap.
One other thing that's odd is that for the first 15 or so seconds after the garbage collection occurs, if I try to use the handle, java gives an EXCEPTION_ACCESS_VIOLATION. BUT if I don't use the handle until after those 15 seconds or so, I can look at the memory and see that it has been reinitialized (or so I think).
Could you please tell me more about why you thought that placing the handle (which is a JNative Pointer object) into the global map would prevent it from being affected by Java's garbage collector?
I tried making a global HashMap and adding my handlePtr into it, but it still seemed to nullify my native memory after the garbage collection.
So I allocate in JNative 4 bytes for the handle which is a pointer. Do I need to allocate more bytes for the object that that handle actually represents? I think my library is doing that for me.
Also, what's the difference between a globalmemoryblock and a nativememoryblock and when would I need to create those objects?
actually I'm fairly sure I didn't download the latest version from the cvs web browser because "Pointer buf = Pointer.createPointerFromString(values);" didn't work.
bug found:
after looking at the api I noticed that on a dispose() call to a JNative object, you can no longer use the dll.
My code:
write()
{
JNative fs = new JNative("TheDLL.dll", "write");
fs.setRetVal(Type.INT);
fs.setParameter(0, handleAddress);
fs.setParameter(1, start);
fs.setParameter(2, number);
fs.setParameter(3, values);
fs.invoke();
}
Thubby was close, and I thank him greatly for his patience and tips. Though my Pointers did not need to have a global reference, my **JNative** object did. When write() was called, fs is a local variable, and its reference is lost. When its reference is lost, the gc() will eventually call finalize - which I believe calls dispose(). Dispose() makes it so I can no longer use the dll. I needed a reference for my jnative object.
Thubby, thanks again.
jb
No you have to download the complete source code (no jar or whatever) from the CVS. Not only one file but the complete source.
Your problem is (in my opinion) exactly what I fixed in CVS. dispose() is deprecated and no longer used in the latest version and I completely rewrote the function-pointer caching. Now at least one instance of each dll is kept in memory so that GC cannot dispose it. Removing dispose() from your implementation might cause a memory-leak while fixing your problems though.
I compiled a test version with the latest CVS code here: http://home.arcor.de/thubb/JNative/JNative.jar
Please try that one and tell me if it works for you.
Thubby
I already found the bug and I got it working with the released 1.3.2, but I will try to find some time to run it with the latest JNative.jar and see how it goes.