将字符串传递给JNI时的访问冲突((0xc0000005))

时间:2012-10-29 18:42:02

标签: c++ java-native-interface

我有一个简单的java类,它通过JNI调用一些用C ++实现的本机方法。

java代码看起来像这样

String in_test="./xml/input/imagen_0023.xml";
//String in_test="avc";
String out_test=acr.testString2(in_test);
System.out.println("test: " + out_test);

testString2的实现在一个dll中,由java程序直接调用。 testString2方法的定义如下。

JNIEXPORT jstring JNICALL Java_com_accsa_ocr_AutomaticCharacterRecognition_testString2(JNIEnv *env, jobject obj, jstring string) 
{
    const char *str = env->GetStringUTFChars(string, 0);

    //std::string s=amt_test_string(str);
    std::string s="hello: "+(std::string)str;
    env->ReleaseStringUTFChars(string, str);
    return env->NewStringUTF(s.c_str());
}

调用的amt_test_string在别处定义(另一个dll):

std::string AMT_EXPORT amt_test_string(std::string in)
{
    std::string s="path: "+in;
    std::cout<<s<<std::endl;
    return s;
}

如果我像这样运行它可以很好地工作,但是当我取消注释时 std :: string s = amt_test_string(str) 我收到如下访问冲突错误:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x77ae2cc7, pid=8072, tid=7328
#
# JRE version: 7.0_09-b05
# Java VM: Java HotSpot(TM) Client VM (23.5-b02 mixed mode, sharing windows-x86 )
# Problematic frame:
# C  [ntdll.dll+0x52cc7]  RtlFreeHeap+0xcd

但这种行为在某种程度上是不稳定的。如果我减少输入参数的长度,即使用

//String in_test="avc"; 

程序再次运作。从我学习谷歌搜索,它是与发布后使用堆栈分配变量相关的东西,但我真的不知道如何调试它。

编辑1:我正在使用Visual Studio 2010和Oracle的JDK 1.7.09在Windows 7 32位上进行编译

编辑2:AMT_EXPORT宏只是导出符号的便捷捷径。请参阅下面的定义:

#ifdef WIN32
    #ifdef AMT_EXPORTS
        #define AMT_EXPORT __declspec(dllexport)
    #else
        #define AMT_EXPORT __declspec(dllimport)
    #endif
#else
    #define AMT_EXPORT
#endif

2 个答案:

答案 0 :(得分:1)

我认为你不应该将const char *强制转换为std::string

std::string s="hello: "+(std::string)str;

通过调用相应的std :: string构造函数替换它。

答案 1 :(得分:0)

为了调试JNI代码,在this article中发布的方法可能很有用(它是关于使用Netbeans和Visual Studio调试JNI)。这很简单 - 只需启动Java程序,然后在Visual Studio中选择Debug - &gt;附加到进程并选择运行程序的java.exe进程。

当您向C ++代码添加断点时,Visual Studio将打破它们。沃伊拉:)