C++で実装されたいくつかのネイティブメソッドをJNI経由で呼び出す単純なJavaクラスがあります。
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の実装は、Javaプログラムによって直接呼び出される1つのdllにあります。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:VisualStudio2010とOracleのJDK1.7.09を使用してWindows732ビットでこれをコンパイルしています
編集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