如何调试 Java 应用程序的 C++ dll

How do debug C++ dll for a Java application

本文关键字:应用程序 C++ dll Java 何调试 调试      更新时间:2023-10-16

我为java应用程序创建了一个C++ dll。 如果我单独启动它,我会让 dll 在应用程序中工作,其中包括一个非常长的批处理文件来获取所有正确的参数。 我想尝试调试我在Visual Studio 2010中创建的dll。 我尝试将命令行和参数放入 Visual Studio 中的调试属性页中。 虽然我无法让应用程序正确启动。

启动应用程序的命令行如下所示,假设应用程序是应用程序名称...

   start "ApplicationName" "C:AppDirectoryjrebinjavaw" -D sun.java2d.nodraw=true -Xms24m -Xmx128m -classpath "C:AppDirectoryclasses;C:AppDirectoryclassesiText.jar" ApplicationName

关于如何为此设置调试设置的任何想法?关于在哪里可以找到有关此文档的任何想法?

我会强烈考虑以下几点:

  1. 如果可能,构建 JNI,使执行工作的代码对 JNI 一无所知。 让它只接收本机C++内容作为参数,并返回本机C++内容作为返回值,并且不调用任何 JNIEnv 函数。
  2. 有一个填充层,该填充层具有 Java 类中本机方法的实际实现。 填充层将知道如何调用 JNIEnv 函数来提取参数,将它们转换为本机C++对象并将它们传递给工作代码。 同样,该层将知道如何将C++对象转换回 Java 对象。 例如,如果一个工作线程函数返回一个std::string,则填充层将知道如何调用 JNIEnv 函数以使本机方法将 Java String返回给 JVM。

我知道事情不能总是这样构建,但它有一些不错的优势:

  1. 它将允许您编写一个C++程序来直接驱动工作线程代码。 这样可以更快、更轻松地测试代码,而不必将 Java 应用程序操作到以您想要的方式使用代码的状态。
  2. 您将能够在调试器、valgrind、内存分析器等下仅运行代码,而无需在该工具下运行整个 JVM。 这使得确定可能泄漏的内存、缓冲区溢出等变得更加容易,而不会被 JVM 内部操作引起的"噪音"淹没。

确实,这种方法意味着没有测试填充层。 但是由于填充层只是在Java世界和C++世界之间转换对象,因此希望它非常简单,因此可以在完整的Java应用程序的上下文中进行测试。

在我的应用程序中,我添加了在启动时检查命令行选项的逻辑,并在命令行选项传递给它时调用 DebugBreak。

我这样做是因为我的应用程序经常在相当复杂的脚本中调用,有时很难甚至不可能使用脚本设置的正确环境(路径、环境变量、临时文件等(从调试器启动应用程序。

因此,如果将特定的命令行选项传递给 DLL,只需调用 DebugBreak(请参阅 http://msdn.microsoft.com/en-us/library/windows/desktop/ms679297%28v=vs.85%29.aspx(。

当断点关闭时,JIT 调试器将显示一个弹出窗口,你可以在其中启动或附加调试器。