Wednesday, June 24, 2009

Passing wrapped C++ objects to Java

In the Toy, C++ code generates an Event, and passes it to Java for processing.
The flow is
Client class (Cclient) creates C++ SimpleEvent (launchEvent)
cClient calls getJEMConnector()->addEvent(*launchEvent);
addevent attaches the C++ thread to the JVM,
creates a Java SimpleEvent wrapper (jSimpleEvent)
calls addEvent(jSimpleEvent) on the Java EventMachine

An now it's up to Java to further handle the event.

Object life cycles are tricky when there are multiple threads. Calling a Java constructor from C++ is no fun because of the weird signature stuff, i.e. "", "(JZ)V" to call the constructor that takes a (long)pointer and a boolean argument.
Then there is Local/Global reference issue. DeleteGlobalRef must be called within C++, before the object is destroyed, on some JavaENV, that should have been cached earlier. This is on top of the memory management problem, as discussed earlier.

I'm going to do some memory leak checks now. I'll be surprised if there are none, because nowhere in C++ do I call DeleteGlobalRef for the SimpleEvent wrapper.

Monday, June 22, 2009

Allocate objects from the JVM

My Event and threading mechanics are all going to be in Java. But I still create some events from C++, wrap them in a Java class, and add them to the queue. When they are processed, I destroy them, and clear the queue, so there are no references.

This created a memory management problem. The "new" was in c++, but the "delete" is in Java. So I ended up overriding the new and delete operators, and having them use the JVM for resources. This seems to work.

Saturday, June 20, 2009

Note to self, varargs stuff are all macros

So, I leared how to use varargs.

Not just declaring a varargs function and getting the arguments.
No, the trick was to get a va_list and pass it on to something like vswprintf. My problem was that whenever I had a number in my va_list, it would get scrambled in the output.

The thing to learn was that all the varargs stuff is just pointer arithmetic on a single char *, obfuscated by macros. The macros create hidden variables, which change state on every use of va_start(), va_arg(), va_list(). So, you can't use any of the arguments passed to your function if you want to pass that va_list on to another function. If you ever call va_arg(), you must reset everything bay calling va_end(), va_start() before you pass the va_list.

It's pretty rotten that
A) None of this stuff follows macro naming conventions, i.e VA_START
B) The side effects of using va_start and va_args are undocumented, not even on faqs or forums.

Wednesday, June 17, 2009

Debugging's "attach to process" broke.

Somehow,
Attach to process from "java.exe" does not work since I reinstalled everything.
"java.exe" gets expanded to the the full path, Q:\sdk\jdk1.6.0_14\bin\java.exe

Which does not match the process in the process list, as launched by Netbeans.

It used to work, but now instead of just hitting f5, I must use two menus, search and click. Visual Studio is simply terrible. How can a product with so many iterations stink so bad?

...
Anyway the trick to getting f5 to work again was to use
Q:\sdk\jdk1.6.0_14\jre\bin\java.exe

Note the "jre" in there.

Sigh. For whatever reason , MSVC stores this debugging info on a
per-user level, with not even a shadow in the project's .vsproj XML file.

So there is no easy way to store this setting with the project.

Tuesday, June 16, 2009

Mercurial Trap

I really like mercurial.
One of the great things is that you have local and "other" (remote) repositories. You can happily check in and track changes locally, then later, push your changesets to the remote repository.
But this leads to a usability issue. You can *forget* to push your changes, and you can neglect to have a remote repo at all.
This just happened to the .swg I made for SWIG. When my drive was corrupted, I lost the work I had done. In this case it was only a few minutes to re-create it. But it could have been bad.

Mercurial does allow practically unlimited extensions, so I could make mercurial automatically create a remote repo when I create a local one. I could also make some kind of nag feature for pushing every day or something.

Build environment

Just for reference, here are the tools and libraries that need to be installed.

*** Tools ***
Netbeans 6.5+
MSVC 2008
Ant 1.7+
CUDA 2.2
Mercurial 1.2+
swigwin (customized!!)
boost-build

*** Libraries ***
jargs
jinvoke
CUDA 2.2 SDK
freeglut (customized!!)
boost_1_38_0 (with static+multithreaded+debug compilation)

*** Projects ***
filesystemmanagement
JNIAntTasks

Friday, June 12, 2009

System woes.

Diskkeeper corrupted my filesystem.
Prudence means that I have a remote repository, and that I've only lost a day of changes, but that assumes that ONLY my local repo is damaged, and not any of the other files (binaries!!!) on that volume. I expect that there is corruption all over this drive, and I must reinstall EVERYTHING. This sucks.
I am looking a one hell of a lot of stuff to download and install.

The week of work that I have not posted about was a new Java based event system. To get this to work, I installed SWIG, a general purpose c/c++ -> other language integration tool. But strangely enough, SWIG does not support unicode for Java, and so I had to mess around for a day creating a SWING typemapping file. ick!

It works, but then my filesystem was corrupted by Diskeeper.

Thursday, June 4, 2009

Now I need a whole new event-loop.

ImageFactory works.
I had to customize FreeGlut to share the HWND window handle that it creates when it opens the main Window. From that I can call wglCreateContext and make that rendering context current. I'm not sure how to get OpenGL rendering context without ever opening an Window....
Anyway, ImageFactory is now dependent on data that must be requested from the UpperDeck, but I've run into insurmountable system-messaging bugs.

Currently, the Toy uses FreeGlut to manage windowing, keyboard, etc.
I am now convinced that the main-loop of Glut breaks Swing, and maybe all Java events. I suspect that the system messages are held up somehow, and are only passed along after the "main window" closes.

The irony is that I'm not going to use the FreeGlut main loop, Swing, or even a screen window. But for testing etc, I need a GUI for control and communication.
So I have to dive into replacing the main loop before I wanted to.
Dang.

Oh, and there are still bogus exceptions thrown from within the Nvidia drivers at "exit". These propagate up and crash the JVM.

Dang again.