Jared Bolin
Jared Bolin

Reputation: 43

How do debug C++ dll for a Java application

I have created a C++ dll for a java application. I have the dll working within the application if I launch it separately, which includes a very lengthy batch file to get all of the correct arguments. I would like to try an debug the dll that I created in Visual Studio 2010. I have tried putting the command line and arguments into the debugging property page in visual studio. Although I am not able to get the application to launch correctly.

The command line to launch the application looks like this assuming the application is ApplicationName...

   start "ApplicationName" "C:\AppDirectory\jre\bin\javaw" -D sun.java2d.nodraw=true -Xms24m -Xmx128m -classpath "C:\AppDirectory\classes\;C:\AppDirectory\classes\iText.jar" ApplicationName

Any ideas on how to property setup the debug settings for this? Any ideas on where I could find some documentation on this?

Upvotes: 1

Views: 2322

Answers (2)

QuantumMechanic
QuantumMechanic

Reputation: 13946

I would strongly consider the following:

  1. If possible, structure the JNI such that the code which does the work knows nothing about JNI. Have it receive only native C++ stuff as arguments and return native C++ stuff as return values, and not call any JNIEnv functions.
  2. Have a shim layer that has the actual implementations of the native methods in your Java classes. The shim layer will know how to call JNIEnv functions to extract the parameters, turn them into native C++ objects and pass them to the working code. Likewise, this layer will know how to turn the C++ objects back into Java objects. For example, if a worker function returns a std::string, the shim layer will know how to call JNIEnv functions to have the native method return a Java String back to the JVM.

I understand that things can't always be structured this way, but there are some nice advantages to it:

  1. It will allow you to write a C++ program to drive the worker code directly. This can make it much faster and easier to test your code rather than having to manipulate your Java app into a state where it is using your code how you want to test.
  2. You will be able to run just your code under a debugger, valgrind, memory profilers, etc. without having to run the whole JVM under the tool. This makes it much easier to pin down what memory may be being leaked, buffers overrun, etc. without being swamped in "noise" caused by JVM internal operations.

It is true that this approach means the shim layer isn't being tested. But since the shim layer is only translating objects between the Java world and the C++ world it is hopefully pretty simple and thus amenable to being testing in the context of the full Java app.

Upvotes: 1

Patrick
Patrick

Reputation: 23619

In my application I added logic that checks a command line option at startup and calls DebugBreak if the command line option was passed to it.

I did this because my application is often called in quite complex scripts and it was sometimes very hard or even impossible to launch the application from the debugger with the correct environment (path, environment variables, temporary files, ...) set by the script.

So, simply call DebugBreak (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms679297%28v=vs.85%29.aspx) if a specific command line option is passed to your DLL.

When the breakpoint goes off, the JIT debugger will show a popup in which you can start or attach your debugger.

Upvotes: 0

Related Questions