Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用jni包装C DLL?_Java_C_Dll_Java Native Interface - Fatal编程技术网

Java 如何使用jni包装C DLL?

Java 如何使用jni包装C DLL?,java,c,dll,java-native-interface,Java,C,Dll,Java Native Interface,我正在从事一个Java/Eclipse项目,需要通过C DLL更改一个过时的库jar 为此,我使用javac和javah命令,创建.h文件,然后编写一个.c文件 C文件将调用C DLL,我将在一个新的Java DLL中编译所有JNIC项目,并使用loadLibrary 发生的事情是,DLL需要复杂的参数,我不知道如何正确执行(我对Java和jni不熟悉) 这是需要包装的DLL使用的.h文件 typedef unsigned char u_char; typedef unsigned int

我正在从事一个Java/Eclipse项目,需要通过C DLL更改一个过时的库jar

为此,我使用javac和javah命令,创建.h文件,然后编写一个.c文件

C文件将调用C DLL,我将在一个新的Java DLL中编译所有JNIC项目,并使用loadLibrary

发生的事情是,DLL需要复杂的参数,我不知道如何正确执行(我对Java和jni不熟悉)

这是需要包装的DLL使用的.h文件

typedef unsigned char  u_char;
typedef unsigned int   u_int;
typedef unsigned short u_short;

typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
                 const u_char *);

typedef struct _B
{
  char addr[50];
  int port;
} B;

typedef struct _A
{
  B *links;
  int nb_links;
} A;

typedef enum {0, 1, 2} E;

void set_enum(E debug);
void set_name(const char *name);
void message(const char *format,...);
void init_link(B *link);   
A init_links(int nb_links);
void free_links(A *link_set);
int init_capture(int inum, const B links, int defragment, pcap_handler packet_handler);
int init_capture_from_file(const char *input_file_name, const A links, int defragment, pcap_handler packet_handler);
这是Java文件(未完成)

这里是我对C文件的尝试

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>
#include <Hello.h>
#include <Hello_E.h>
#include <Hello_A.h>
#include <Hello_B.h>

typedef struct _B
{
  char addr[50];
  int port;
} B;

typedef struct _A
{
  B *links;
  int nb_links;
} A;

typedef enum {0, 1, 2} E;

JNIEXPORT void JNICALL Java_Hello_set_1enum(JNIEnv *env, jobject object, jobject debug)
{
    jmethodID enumGetValueMethod = (*env)->GetMethodID(env, (*env)->FindClass(env, "Hello$E"), "ordinal", "()I");
    jint value = (*env)->CallIntMethod(env, debug, enumGetValueMethod);
    printf("set_1enum: %d\n", value);

    E enum_debug = value;
    //Call true dll fonction
    //set_debug(E debug);
}


JNIEXPORT void JNICALL Java_Hello_set_1name(JNIEnv *env, jobject object, jstring name)
{
    const char *str = (*env)->GetStringUTFChars(env, name, 0);
    if (str == NULL)
    {
        printf("Error in set_1name\n");
        return;
    }
    printf("set_1name: %s\n", str);

    //Call true dll fonction
    //set_name(const char *name);

    (*env)->ReleaseStringUTFChars(env, name, str);
}

JNIEXPORT void JNICALL Java_Hello_message(JNIEnv *env, jobject object, jobjectArray str_array)
{
    int length = (*env)->GetArrayLength(env, str_array);
    const char *format[length];

    for (int i = 0; i < length; i++)
    {
        jstring string = (jstring) (*env)->GetObjectArrayElement(env, str_array, i);
        const char *rawString = (*env)->GetStringUTFChars(env, string, 0);

        format[i] = malloc(strlen(rawString) + 1);
        strcpy((char *)format[i],rawString);
        printf("message - format[i]: %s   - raw string: %s\n", format[i], rawString);
        (*env)->ReleaseStringUTFChars(env, string, rawString);
        printf("message format[i]: %s   i:%d\n", format[i], i);
    }

    //Call true dll fonction
    // message(const char *format,...);

    // free
     for (int i = 0; i < length; i++)
    {
        free((char *)format[i]);
    }
}

JNIEXPORT void JNICALL Java_Hello_1init_1link(JNIEnv *env, jobject object, jobjectArray jlinks)
{
    int length = (*env)->GetArrayLength(env, jlinks);
    B links[length];

    for (int i = 0; i < length; i++)
    {

        B link;
        jobject  objectLink = (*env)->GetObjectArrayElement(env, jlinks, i);
        jclass afdxLink = (*env)->FindClass(env, "Hello$B");

        // get the addr char [] and stock it in links[i].addr as char [50]

        jfieldID  fid = (*env)->GetFieldID (env, afdxLink, "port", "I");
        myInt = (*env)->GetIntField (env, objectLink, fid);
        link.port = myInt;

        links[i] = link;
        printf("init_1link[i].port: %d\n", links[i].port);
    }

    //Call true dll fonction
    // init_link(B *link);
}

JNIEXPORT jobject JNICALL Java_Hello_init_1links(JNIEnv *env, jobject object, jint nb_links)
{
    jclass jni_a = (*env)->FindClass(env, "Hello$A");
    jclass jni_b = (*env)->FindClass(env, "Hello$B");
    A link_set;
    link_set.links = NULL;
    link_set.nb_links = nb_links;

    printf("init_1links :%d\n", link_set.nb_links);

    //Call true dll fonction
    // link_set = init_links(nb_links);


    jmethodID constructor;
    jobject link_set_obj;

    if (afdx_link_set == NULL || afdx_link == NULL)
    {
        printf("aio_1init_1links - Couldn't create new jclass from class AFDXLinkSet or AFDXLink\n");
        return (NULL);
    }
    if ((constructor = (*env)->GetMethodID(env, afdx_link_set, "<init>", "()Hello$AFDXLinkSet")) == NULL)
    {
        printf("aio_1init_1links - Couldn't create new jmethodID from class AFDXLinkSet\n");
        return (NULL);
    }
    if ((link_set_obj = (*env)->NewObject(env, afdx_link_set, constructor)) == NULL)
    {
        printf("aio_1init_1links - Couldn't create new jobject from class AFDXLinkSet\n");
        return (NULL);
    }
    return (link_set_obj);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类型定义结构
{
字符地址[50];
国际港口;
}B;
类型定义结构
{
B*链接;
国际nbu链接;
}A;
typedef枚举{0,1,2}E;
JNIEXPORT void JNICALL Java_Hello_set_1enum(JNIEnv*env,jobject对象,jobject调试)
{
jmethodID enumGetValueMethod=(*env)->GetMethodID(env,(*env)->FindClass(env,“Hello$E”),“ordinal”,“I”);
jint value=(*env)->CallIntMethod(env,debug,enumGetValueMethod);
printf(“设置数量:%d\n”,值);
E enum_debug=值;
//调用真dll函数
//设置_调试(E调试);
}
JNIEXPORT void JNICALL Java_Hello_set_1name(JNIEnv*env,jobject对象,jstring名称)
{
const char*str=(*env)->GetStringUTFChars(env,name,0);
如果(str==NULL)
{
printf(“set_1name\n中的错误”);
返回;
}
printf(“设置名称:%s\n”,str);
//调用真dll函数
//设置名称(常量字符*名称);
(*env)->ReleaseStringUTFChars(env,name,str);
}
JNIEXPORT void JNICALL Java_Hello_消息(JNIEnv*env,jobject对象,jobjectArray str_数组)
{
int length=(*env)->GetArrayLength(env,str_数组);
常量字符*格式[长度];
for(int i=0;iGetObjectArrayElement(env,str_数组,i);
const char*rawString=(*env)->GetStringUTFChars(env,string,0);
格式[i]=malloc(strlen(rawString)+1);
strcpy((char*)格式[i],原始字符串);
printf(“消息-格式[i]:%s-原始字符串:%s\n”,格式[i],原始字符串”);
(*env)->ReleaseStringUTFChars(env,string,rawString);
printf(“消息格式[i]:%si:%d\n”,格式[i],i”);
}
//调用真dll函数
//消息(常量字符*格式,…);
//免费的
for(int i=0;iGetArrayLength(env,jlinks);
B链接[长度];
for(int i=0;iGetObjectArrayElement(env,jlinks,i);
jclass afdxLink=(*env)->FindClass(env,“Hello$B”);
//获取addr char[]并将其存储在链接[i]中。addr as char[50]
jfieldID fid=(*env)->GetFieldID(env,afdxLink,“port”,“I”);
myInt=(*env)->GetIntField(env、objectLink、fid);
link.port=myInt;
链接[i]=链接;
printf(“初始化链接[i]。端口:%d\n”,链接[i]。端口);
}
//调用真dll函数
//初始链接(B*链接);
}
JNIEXPORT jobject JNICALL Java_Hello_init_1Link(JNIEnv*env、jobject对象、jint nb_链接)
{
jclass jni_a=(*env)->FindClass(env,“Hello$a”);
jclass jni_b=(*env)->FindClass(env,“Hello$b”);
链接集;
link_set.links=NULL;
link_set.nb_links=nb_links;
printf(“初始链接:%d\n”,链接集.nb\u链接);
//调用真dll函数
//链接集=初始链接(nb链接);
jmethodID构造函数;
作业对象链接_集合_对象;
if(afdx_link_set==NULL | | afdx_link==NULL)
{
printf(“aio_1nit_1links-无法从类AFDXLinkSet或AFDXLink创建新的jclass\n”);
返回(空);
}
if((构造函数=(*env)->GetMethodID(env,afdx_-link_-set,“,”()Hello$AFDXLinkSet”)==NULL)
{
printf(“aio_1nit_1links-无法从类AFDXLinkSet创建新的jmethodID\n”);
返回(空);
}
if((link\u set\u obj=(*env)->NewObject(env、afdx\u link\u set、构造函数))==NULL)
{
printf(“aio_1nit_1links-无法从类AFDXLinkSet创建新作业对象\n”);
返回(空);
}
返回(链接设置对象);
}
第一个函数(
set_enum
set_name
message
)可以工作,但稍后需要调用DLL函数,这可能会很棘手。最后两个(init_link和init_links)更难,我找不到如何从init_link中的jobjectarray中获得一个好的字符[50]值,而对于init_links,我在构建jobject时遇到了麻烦

您能告诉我在Java和C DLL之间创建JNI DLL是否正确吗


还有一些关于从内部类获取参数或创建jni参数的技巧,我们将不胜感激。

考虑桥接而不是包装。参见依赖倒置原理。首先编写应用程序从服务请求的Java接口。它应该是自然的、惯用的Java。很抱歉,你能给我更多的信息吗?在编写库以满足应用程序的需要时,我对如何使用Jnitis应用的依赖项反转有点迷茫。(它不适用于编写多个应用程序可能会以不同方式使用的通用库)应用程序定义它从库中需要的内容,并且编写库是为了满足它。参考这个。这似乎适用于你的情况,因为你说你正在替换现有的应用程序中的一个旧的库B。也许从旧的提取一个接口,也许?考虑桥接而不是包装。参见依赖倒置原理。首先编写应用程序从服务请求的Java接口。它应该是自然的、惯用的Java
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>
#include <Hello.h>
#include <Hello_E.h>
#include <Hello_A.h>
#include <Hello_B.h>

typedef struct _B
{
  char addr[50];
  int port;
} B;

typedef struct _A
{
  B *links;
  int nb_links;
} A;

typedef enum {0, 1, 2} E;

JNIEXPORT void JNICALL Java_Hello_set_1enum(JNIEnv *env, jobject object, jobject debug)
{
    jmethodID enumGetValueMethod = (*env)->GetMethodID(env, (*env)->FindClass(env, "Hello$E"), "ordinal", "()I");
    jint value = (*env)->CallIntMethod(env, debug, enumGetValueMethod);
    printf("set_1enum: %d\n", value);

    E enum_debug = value;
    //Call true dll fonction
    //set_debug(E debug);
}


JNIEXPORT void JNICALL Java_Hello_set_1name(JNIEnv *env, jobject object, jstring name)
{
    const char *str = (*env)->GetStringUTFChars(env, name, 0);
    if (str == NULL)
    {
        printf("Error in set_1name\n");
        return;
    }
    printf("set_1name: %s\n", str);

    //Call true dll fonction
    //set_name(const char *name);

    (*env)->ReleaseStringUTFChars(env, name, str);
}

JNIEXPORT void JNICALL Java_Hello_message(JNIEnv *env, jobject object, jobjectArray str_array)
{
    int length = (*env)->GetArrayLength(env, str_array);
    const char *format[length];

    for (int i = 0; i < length; i++)
    {
        jstring string = (jstring) (*env)->GetObjectArrayElement(env, str_array, i);
        const char *rawString = (*env)->GetStringUTFChars(env, string, 0);

        format[i] = malloc(strlen(rawString) + 1);
        strcpy((char *)format[i],rawString);
        printf("message - format[i]: %s   - raw string: %s\n", format[i], rawString);
        (*env)->ReleaseStringUTFChars(env, string, rawString);
        printf("message format[i]: %s   i:%d\n", format[i], i);
    }

    //Call true dll fonction
    // message(const char *format,...);

    // free
     for (int i = 0; i < length; i++)
    {
        free((char *)format[i]);
    }
}

JNIEXPORT void JNICALL Java_Hello_1init_1link(JNIEnv *env, jobject object, jobjectArray jlinks)
{
    int length = (*env)->GetArrayLength(env, jlinks);
    B links[length];

    for (int i = 0; i < length; i++)
    {

        B link;
        jobject  objectLink = (*env)->GetObjectArrayElement(env, jlinks, i);
        jclass afdxLink = (*env)->FindClass(env, "Hello$B");

        // get the addr char [] and stock it in links[i].addr as char [50]

        jfieldID  fid = (*env)->GetFieldID (env, afdxLink, "port", "I");
        myInt = (*env)->GetIntField (env, objectLink, fid);
        link.port = myInt;

        links[i] = link;
        printf("init_1link[i].port: %d\n", links[i].port);
    }

    //Call true dll fonction
    // init_link(B *link);
}

JNIEXPORT jobject JNICALL Java_Hello_init_1links(JNIEnv *env, jobject object, jint nb_links)
{
    jclass jni_a = (*env)->FindClass(env, "Hello$A");
    jclass jni_b = (*env)->FindClass(env, "Hello$B");
    A link_set;
    link_set.links = NULL;
    link_set.nb_links = nb_links;

    printf("init_1links :%d\n", link_set.nb_links);

    //Call true dll fonction
    // link_set = init_links(nb_links);


    jmethodID constructor;
    jobject link_set_obj;

    if (afdx_link_set == NULL || afdx_link == NULL)
    {
        printf("aio_1init_1links - Couldn't create new jclass from class AFDXLinkSet or AFDXLink\n");
        return (NULL);
    }
    if ((constructor = (*env)->GetMethodID(env, afdx_link_set, "<init>", "()Hello$AFDXLinkSet")) == NULL)
    {
        printf("aio_1init_1links - Couldn't create new jmethodID from class AFDXLinkSet\n");
        return (NULL);
    }
    if ((link_set_obj = (*env)->NewObject(env, afdx_link_set, constructor)) == NULL)
    {
        printf("aio_1init_1links - Couldn't create new jobject from class AFDXLinkSet\n");
        return (NULL);
    }
    return (link_set_obj);
}