0

So, i have visual studio consloe project that compile to .dll file. I've created simple windows form System::Windows::Forms::Form

I've created a .java file:

 import java.io.Serializable;


public class MyBean implements Serializable{

    /**
     * 
     */
    static{
        System.loadLibrary("MyBean");
}
    private static final long serialVersionUID = 1L;


    private static native String getDateCpp();


    public String getDate(){
        return getDateCpp();
    }



}

compiled it and generate a .h file by javah:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyBean */

#ifndef _Included_MyBean
#define _Included_MyBean
#ifdef __cplusplus
extern "C" {
#endif
#undef MyBean_serialVersionUID
#define MyBean_serialVersionUID 1i64
/*
 * Class:     MyBean
 * Method:    getDateCpp
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MyBean_getDateCpp
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

and implemented a .cpp file that shows Form:

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include "Form1.h"
#include "MyBean.h"
#include <string>
#include <vcclr.h>
using namespace std;


bool To_string( String^ source, string &target )
{
    pin_ptr<const wchar_t> wch = PtrToStringChars( source );
    int len = (( source->Length+1) * 2);
    char *ch = new char[ len ];
    bool result = wcstombs( ch, wch, len ) != -1;
    target = ch;
    delete ch;
    return result;
}

JNIEXPORT jstring JNICALL Java_MyBean_getDateCpp
    (JNIEnv * env, jclass jcl){
        Form1^ form = gcnew Form1();
        form->Show();

        String^ text = form->text;
        string stdString = "";


        if(To_string(text,stdString))
            return  (*env).NewStringUTF(stdString.c_str());
        else
            return (*env).NewStringUTF("blad");
}

after compilling succesfully i'm getting error form java after i try to call c++ function:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007f9324f811c, pid=4404, tid=4800
#
# JRE version: Java(TM) SE Runtime Environment (7.0_45-b18) (build 1.7.0_45-b18)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.45-b08 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [KERNELBASE.dll+0x3811c]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# D:\studia\semestr 7\java\lab05\hs_err_pid4404.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

and log is long, i'll not post it here.

What i'm doing wrong?

4

2 回答 2

1

呃..

  1. wcstombs从不返回小于 0 的值。请参见此处:http ://www.cplusplus.com/reference/cstdlib/wcstombs/

  2. 这被标记为 c++,所以我认为你应该使用env->而不是(*env).. 没什么大不了的,但是嗯..

  3. 我不确定你是否需要它,但我认为你extern "C"在你的 JNI 函数之前失踪了。

最后,确保您的调用约定是正确的。不久前我遇到了同样的问题/异常/转储:Loading JNI Dll

我通过更改调用约定并使用 .def 文件导出来解决它。我相信您需要解决的只是调用约定。不需要 .def 文件;只是想我还是会提到它。

每当您收到该错误时,都是由于调用约定问题。很少是由于权限,但这也是值得关注的。也许您可能需要以管理员身份运行。

于 2013-11-12T22:24:22.533 回答
0

我打电话有一个错误,form->Show();但我应该打电话form->ShowDialog();

来自 MSDN:

显示对话框()

您可以使用此方法在应用程序中显示模式对话框。调用此方法时,它后面的代码要等到对话框关闭后才会执行。

节目()

显示控件相当于将 Visible 属性设置为 true。调用 Show 方法后,Visible 属性返回 true 值,直到调用 Hide 方法。

因此,当我调用 show 时,我得到了要转换的空字符串,并且我的窗口只显示了一秒钟或更短的时间,现在它是模态的,它等待关闭,然后执行其余代码。JNI 被正确实施并且工作得很好。

于 2013-11-15T07:46:41.580 回答