Java/JNI/MSVC Java.lang.UnsatifiedLinkError到我的DLL函数

Java/JNI/MSVC Java.lang.UnsatifiedLinkError到我的DLL函数,java,visual-c++,dll,linker,java-native-interface,Java,Visual C++,Dll,Linker,Java Native Interface,我正在为工作编写libvpx的视频编码器包装,但在Java中,当我尝试调用这些函数时,得到了Java.lang.UnsatisfiedLinkError 以下是我的Java代码: package default; class YE_Vpx { native int create_stream( String path, int w, int h, int fps ); native void finalize_stream( int streamid ); native

我正在为工作编写libvpx的视频编码器包装,但在Java中,当我尝试调用这些函数时,得到了Java.lang.UnsatisfiedLinkError

以下是我的Java代码:

package default;

class YE_Vpx {
    native int create_stream( String path, int w, int h, int fps );
    native void finalize_stream( int streamid );
    native void append_stream( int streamid, int[] pixels );
    native void finalize_streams( );

    static {
        System.loadLibrary("libvpx_ye"); // This loads the DLL just fine (windows 7), otherwise it would tell me it wasn't in the java.library.path
    }
}
这是我的C头(由javah生成):

/*不要编辑此文件-它是机器生成的*/
#包括
/*类YE_Vpx的标题*/
#如果不包括(是)(Vpx)
#定义包含的内容
#ifdef_uucplusplus
外部“C”{
#恩迪夫
/*
*类别:YE_Vpx
*方法:创建\u流
*签名:(Ljava/lang/String;III)I
*/
JNIEXPORT jint JNICALL Java_YE_1Vpx_create_1stream
(JNIEnv*、jobject、jstring、jint、jint、jint);
/*
*类别:YE_Vpx
*方法:完成\u流
*签字:(一)五
*/
JNIEXPORT void JNICALL Java\u YE\u 1Vpx\u finalize\u 1stream
(JNIEnv*,jobject,jint);
/*
*类别:YE_Vpx
*方法:追加\u流
*签字:(I[I)V
*/
JNIEXPORT void JNICALL Java_YE_1Vpx_append_1stream
(金塔雷金特jobject JNIEnv*);
/*
*类别:YE_Vpx
*方法:完成\u流
*签字:()五
*/
JNIEXPORT void JNICALL Java\u YE\u 1Vpx\u finalize\u 1streams
(JNIEnv*,jobject);
#ifdef_uucplusplus
}
#恩迪夫
#恩迪夫
这是我的C代码(它引用了我认为无法在这里展示的其他文件):

#包括
#包括
#包括
#包括“ye_vpx.h”//这是javah生成的头文件
#包括“ye_vpx_c.h”//这是大部分肉的位置,我实际上无法发布此文件=/
#ifdef_uucplusplus
外部“C”{
#恩迪夫
JNIEXPORT jint JNICALL Java_YE_1Vpx_create_1stream(JNIEnv*env、jobject obj、jstring path、jint w、jint h、jint fps)
{
jboolean-iscopy;
const jchar*m_path=(*env)->GetStringChars(env、path和iscopy);
jint ret=ye_vpx_create_stream((const char*)m_path,w,h,fps);
(*env)->ReleaseStringChars(env,path,m_path);
返回ret;
}
JNIEXPORT void JNICALL Java_YE_1Vpx_finalize_1stream(JNIEnv*env、jobject obj、jint streamid)
{
ye_vpx_finalize_流(streamid);
}
JNIEXPORT void JNICALL Java_YE_1Vpx_append_1stream(JNIEnv*env、jobject obj、jint streamid、jintArray像素)
{
jint*px=NULL;
整数长度=0;
长度=(*env)->GetArrayLength(env,像素);
px=(jint*)calloc(长度,大小(jint));
(*env)->GetIntArrayRegion(env,像素,0,长度,px);
//px=(jint*)获取阵列元素(环境、像素和iCopy);
ye_vpx_append_流(streamid,px);
自由基(px);
}
JNIEXPORT void JNICALL Java_YE_1Vpx_finalize_1streams(JNIEnv*env,jobject obj)
{
ye_vpx_finalize_streams();
}
#ifdef_uucplusplus
}
#恩迪夫
据我所知,我已经正确导出了所有必要的内容。我正在使用Microsoft Visual C(2010 Express),并且正在链接jvm.lib和jawt.lib,并且正在静态链接MFC和ALT库。我错过了什么吗

我应该提到,在构建DLL时,我得到以下输出:

1> 创建库C:\Users\Alexander\youeye rnd\java rnd\libvpx youeye\msvc\libvpx\u ye\Debug\libvpx\u ye.lib 对象C:\Users\Alexander\youeye rnd\java rnd\libvpx youeye\msvc\libvpx\u ye\Debug\libvpx\u ye.exp

1> 链接:警告LNK4098:defaultlib'LIBCMT'与其他lib的使用冲突;使用/NODEFAULTLIB:library 1>libvpx_ye.vcxproj->C:\Users\Alexander\youeye rnd\java rnd\libvpx youeye\msvc\libvpx_ye\Debug\libvpx_ye.dll


我曾尝试将“忽略特定的默认库”(在Linker>Input下)设置为“/NODEFAULTLIB:libcmt”,但没有效果。我认为这可能是我的问题,但我不能完全确定。

因此有两个问题使得调试变得困难,但都是我的错

首先,当我制作最初的JNI c-header时,我没有在*.Java源代码中包含包名,因为我认为生成的DLL文件对哪个包有点含糊不清,只要它理解它的函数相关的类。因此,我在类上添加了正确的包名redid javah,它用正确的包名

其次,为了解决msvc问题,在Properties>Linker>Input>“Ignore Specific Default Libraries”下,我加入了完整的命令行开关“/NODEFAULTLIB:libcmt”,当时它只希望我加入libcmt,其余的都由它来处理。一旦纠正,它就在编译时没有任何警告

我希望这能帮助一些人在windows上调试他们自己的JNI/DLL问题

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

#ifndef _Included_YE_Vpx
#define _Included_YE_Vpx
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     YE_Vpx
 * Method:    create_stream
 * Signature: (Ljava/lang/String;III)I
 */
JNIEXPORT jint JNICALL Java_YE_1Vpx_create_1stream
  (JNIEnv *, jobject, jstring, jint, jint, jint);

/*
 * Class:     YE_Vpx
 * Method:    finalize_stream
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_YE_1Vpx_finalize_1stream
  (JNIEnv *, jobject, jint);

/*
 * Class:     YE_Vpx
 * Method:    append_stream
 * Signature: (I[I)V
 */
JNIEXPORT void JNICALL Java_YE_1Vpx_append_1stream
  (JNIEnv *, jobject, jint, jintArray);

/*
 * Class:     YE_Vpx
 * Method:    finalize_streams
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_YE_1Vpx_finalize_1streams
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
#include <jni.h>
#include <jni_md.h>
#include <sys/types.h>

#include "ye_vpx.h" // This is the javah generated header
#include "ye_vpx_c.h" // This is where most of the meat is, I can't actually post this file =/

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL Java_YE_1Vpx_create_1stream( JNIEnv *env, jobject obj, jstring path, jint w, jint h, jint fps )
{
    jboolean iscopy;
    const jchar *m_path = (*env)->GetStringChars(env, path, &iscopy);
    jint ret = ye_vpx_create_stream( (const char *)m_path, w, h, fps );
    (*env)->ReleaseStringChars(env, path, m_path);
    return ret;
}

JNIEXPORT void JNICALL Java_YE_1Vpx_finalize_1stream(JNIEnv *env, jobject obj, jint streamid)
{
    ye_vpx_finalize_stream( streamid );
}

JNIEXPORT void JNICALL Java_YE_1Vpx_append_1stream(JNIEnv *env, jobject obj, jint streamid, jintArray pixels)
{
    jint *px = NULL;
    int length = 0;

    length = (*env)->GetArrayLength(env, pixels);
    px = (jint *)calloc( length, sizeof(jint) );
    (*env)->GetIntArrayRegion(env, pixels, 0, length, px);
    //px = (jint *)GetIntArrayElements( env, pixels, &iscopy );
    ye_vpx_append_stream( streamid, px );
    free( px );
}

JNIEXPORT void JNICALL Java_YE_1Vpx_finalize_1streams(JNIEnv *env, jobject obj)
{
    ye_vpx_finalize_streams();
}

#ifdef __cplusplus
}
#endif