我有一个简单的 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