%1 is not a valid Win32 application

末鹿安然 提交于 2021-02-11 08:23:04

问题


I want to make a .dll in Qt, and to use generated .dll in a Java project in Eclipse.

I've followed this tutorial to create a working dll.

The full code that works is given below:

jniProjectExample_JniExample.h

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

#ifndef _Included_jniProjectExample_JniExample
#define _Included_jniProjectExample_JniExample
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jniProjectExample_JniExample
 * Method:    callJavaMethod
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jniProjectExample_JniExample_callJavaMethod
(JNIEnv *, jobject);

/*
 * Class:     jniProjectExample_JniExample
 * Method:    createAndReturnBean
 * Signature: ()LjniProjectExample/Bean;
 */
JNIEXPORT jobject JNICALL Java_jniProjectExample_JniExample_createAndReturnBean
(JNIEnv *, jobject);

/*
 * Class:     jniProjectExample_JniExample
 * Method:    modifyBean
 * Signature: (LjniProjectExample/Bean;)V
 */
JNIEXPORT void JNICALL Java_jniProjectExample_JniExample_modifyBean
(JNIEnv *, jobject, jobject);

/*
 * Class:     jniProjectExample_JniExample
 * Method:    crashTheJvm
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jniProjectExample_JniExample_crashTheJvm
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif

#endif

jniProjectExample_JniExample.cpp

#include "jniProjectExample_JniExample.h"
/* ------------------------------- A PROBLEM
  #include <iostream>
  #include <cstring>
*/

JNIEXPORT void JNICALL Java_jniProjectExample_JniExample_callJavaMethod (JNIEnv * env, jobject obj) {
    jclass jniExampleCls = env->GetObjectClass(obj);

    jmethodID mid = env->GetMethodID(jniExampleCls, "printSomething", "()V");

    env->CallVoidMethod(obj, mid);
}

JNIEXPORT jobject JNICALL Java_jniProjectExample_JniExample_createAndReturnBean  (JNIEnv *env, jobject obj) {
    jclass beanClass = env->FindClass("jniProjectExample/Bean");
    jmethodID constructorMethodId = env->GetMethodID(beanClass, "<init>", "()V");
    jobject bean = env->NewObject(beanClass, constructorMethodId);

    jstring newString = env->NewStringUTF("this bean has been created in Java_jniProjectExample_JniExample_createAndReturnBean");

    jmethodID setStringMid = env->GetMethodID(beanClass, "setDataString", "(Ljava/lang/String;)V");

    env->CallVoidMethod(bean, setStringMid, newString );

    return bean;
}

JNIEXPORT void JNICALL Java_jniProjectExample_JniExample_modifyBean  (JNIEnv *env, jobject obj, jobject bean) {
    jclass beanCls = env->GetObjectClass(bean);

    jmethodID setStringMid = env->GetMethodID(beanCls, "setDataString", "(Ljava/lang/String;)V");

    // set the bean member "dataString"
    jstring newString = env->NewStringUTF("world");
    env->CallVoidMethod(bean, setStringMid, newString );

    // set the bean member "dataByteArray"
    jbyteArray newByteArray = env->NewByteArray(5);
    jbyte buffer[5] = {5,4,3,2,1};
    env->SetByteArrayRegion( newByteArray, 0, 5, buffer);

    jmethodID setByteArrayMid = env->GetMethodID(beanCls, "setDataByteArray", "([B)V");

    env->CallVoidMethod(bean, setByteArrayMid, newByteArray );

    /* -----------------------  A PROBLEM
    char bla[] = "something";
    if(strcmp(bla, "label") == 0){
        std::cout<<"strcmp 1";
    }                               
    else {
        std::cout<<"strcmp 2";
    } ------------------------  */
}


JNIEXPORT void JNICALL Java_jniProjectExample_JniExample_crashTheJvm (JNIEnv *env, jobject obj) {
    //stack overflow - http://en.wikipedia.org/wiki/Stack_overflow
    double x[1000000];
}

jniExampleLibrary.pro

#-------------------------------------------------
#
# Project created by QtCreator 2019-03-23T09:43:24
#
#-------------------------------------------------

QT       -= core gui

TARGET = jniExampleLibrary
TEMPLATE = lib

DEFINES += JNIEXAMPLELIBRARY_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


QMAKE_CFLAGS += -std=c++11

macx:INCLUDEPATH += /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/include \
    /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/include/darwin

win32:INCLUDEPATH +=    "C:\Program Files\Java\jdk1.8.0_181\include" \
                        "C:\Program Files\Java\jdk1.8.0_181\include\win32"

SOURCES += \
    jniProjectExample_JniExample.cpp

HEADERS += \
    jni.h \
    jni_md.h \
    jniProjectExample_JniExample.h

unix {
    target.path = /usr/lib
    INSTALLS += target
}

Bean.java

package jniProjectExample;

public class Bean {

    //public members
    public String dataString; 
    public byte[] dataByteArray;

    public Bean() {}

    //getters and setters
    public String getDataString() {
        return dataString;
    }

    public void setDataString(String dataString) {
        this.dataString = dataString;
    }

    public byte[] getDataByteArray() {
        return dataByteArray;
    }

    public void setDataByteArray(byte[] dataByteArray) {
        this.dataByteArray = dataByteArray;
    } 

    @Override
    public String toString(){
        String ret = "string = " + dataString;

        ret += " / byteArray =";
        if ( dataByteArray != null ) {
            for ( byte b : dataByteArray) {
                ret += " " + b;
            }
        }

        return  ret; 
    }
}

JniExample.java

package jniProjectExample;

public class JniExample {
    static {
        System.loadLibrary("jniExampleLibrary");
    }

    // native methods
    /**
     * this method calls printSomething
     */
    public native void callJavaMethod();

    /**
     * this method creates an instance of Bean and returns it
     */
    public native Bean createAndReturnBean();

    /**
     * this method takes an instance of Bean as parameter and changes the value
     * of its members
     */
    public native void modifyBean(Bean bean);

    /**
     * this method will the JVM when invoked
     */
    public native void crashTheJvm();

    public void printSomething() {
        System.out.println("Thanks for watching this video");
    }

    public void runExample1() {
        System.out.println("starting runExample1...");
        callJavaMethod();
    }

    public void runExample2() {
        System.out.println("starting runExample2...");

        Bean bean = createAndReturnBean();
        System.out.println("returned= " + bean.toString());
    }

    public void runExample3() {
        System.out.println("starting runExample3...");

        Bean bean = new Bean();
        bean.setDataString("hello");

        byte[] byteArray = new byte[] { 0x01, 0x02, 0x03 };
        bean.setDataByteArray(byteArray);

        System.out.println("before: " + bean.toString());
        modifyBean(bean);
        System.out.println("after: " + bean.toString());
    }

    public void runExample4() {
        System.out.println("starting runExample4...");
        crashTheJvm();
    }
}

Main.java

package jniProjectExample;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("Starting JavaMain...");

        System.out.println(System.getProperty("java.library.path"));

        JniExample jniExample = new JniExample();
        jniExample.runExample1();
        jniExample.runExample2();
        jniExample.runExample3();
    //  jniExample.runExample4();
    }

}

Calling dll in java is ok, as long as dll doesn't include any standard c++ functions. As soon as I uncomment this code in jniProjectExample_JniExample.cpp, there's a problem and java application throws an exception saying dll 'is not a valid Win32 application'.

I am at Windows 10 and I use MinGW 64-bit compiler to generate dll. Obviously, there's something about this standard library linkage at runtime, but I can't seem to work it out the whole day, so i would appreciate any help from you guys.

来源:https://stackoverflow.com/questions/55784534/1-is-not-a-valid-win32-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!