[eside-ghost] Código C multiplataforma trabajando con JNI

Arkaitz arkaitzj en gmail.com
Dom Jul 2 20:12:21 CEST 2006


Aupa,
Ando trabajando con java para el PFC y hay ciertas cosas que requieren
manejo a bajo nivel, como la que me preocupa ahora mismo, que trabaja
contra la stack de bluetooth(BlueZ) de linux. Ya se que no hay BlueZ
para windows, eso es otra cosa.
El caso es que he pillado un proyecto por ahi que tiene esa parte
hecha, pero aunque compila tanto en x86 como en ppc solo se ejecuta
bien en x86.
LLega un momento en el que para crear un objeto de Java pasa ciertos
argumentos que creo que provocan una excepción. Me inclino a pensar
que el problema deriva de las diferencias en los tipos básicos de c
entre x86 y ppc.
Pego la función en cuestión a ver si alguien sabe que se le puede hacer.

JNIEXPORT jboolean JNICALL Java_de_avetana_bluetooth_stack_BlueZ_hciInquiry
        (JNIEnv *env, jclass obj, jint dd, jint length, jint
max_num_rsp, jlong flags, jobject agent) {
        /* Perform an HCI inquiry - result is returned as a */
        /* Java InquiryInfo object.                         */
        jclass ii_cls, iid_cls, ba_cls;
        jmethodID ii_con_id, ii_add_id, iid_con_id, ba_con_id;
        jobject info_dev, bdaddr;
        jvalue iid_args[5];

        int num_rsp, i;
        inquiry_info *inq_info = NULL;
        bdaddr_t bdaddr_cpy;

        char *ba_str;
        jstring jba_str;

        //printf("Function called: %s, %i\n"__FILE__, __LINE__);

#ifdef __HCI_DEVICE_HACK__
//      printf("BlueZ.cpp hciInquiry: changing dd=%i => to dd=%i \n", dd, dd);
        dd = HCI_DEVICE_ID;
#endif
        printf("Apunto de hacer el inquiry\n");
        /* Perform the HCI inquiry */
        num_rsp = hci_inquiry(dd, length, max_num_rsp, NULL, &inq_info, flags);
        if (num_rsp < 0)
        {
                printf("Deberia soltar una excepcion\n");
                throwException(env,
"Java_de_avetana_bluetooth_stack_BlueZ_hciInquiry: Inquiry failed");
                return false;
        }
        printf("inquiry hecho\n");

        inquiry_info *inq_info_bak = inq_info;

        ii_cls = env->FindClass("javax/bluetooth/DiscoveryAgent");
        ii_add_id = env->GetMethodID(ii_cls, "deviceDiscovered",
"(Ljavax/bluetooth/RemoteDevice;)V");


        /* For each of the responses, create a new RemoteDevice object */
        /* and add it to the DiscoveryAgent instance.                 */
        iid_cls = env->FindClass("javax/bluetooth/RemoteDevice");
        iid_con_id = env->GetMethodID(iid_cls, "<init>",
"(Ljava/lang/String;BBBSI)V");

        printf("Ids de metodos conseguidas\nCreando %i objetos
RemoteDevice....\n", num_rsp);

        for (i=0; i<num_rsp; i++)
        {
                baswap(&bdaddr_cpy, &inq_info->bdaddr);
                ba_str = batostr(&bdaddr_cpy); // Convert from bdaddr_t to char*
                jba_str = env->NewStringUTF(ba_str);
                iid_args[0].l = jba_str;
                iid_args[1].b = (jbyte)  inq_info->pscan_rep_mode;
                iid_args[2].b = (jbyte)  inq_info->pscan_period_mode;
                iid_args[3].b = (jbyte)  inq_info->pscan_mode;
                /*              iid_args[4].s = (jshort)
inq_info->dev_class[0];
                                iid_args[5].s = (jshort)
inq_info->dev_class[1];
                                iid_args[6].s = (jshort)
inq_info->dev_class[2];*/
                iid_args[4].s = (jshort)    inq_info->clock_offset;
                //              iid_args[5].i =
(jint)((inq_info->dev_class[0] & 0xfc) | ((inq_info->dev_class[1] &
0x1f) << 8) | ((inq_info->dev_class[2] & 0x3ff) << 13));
                iid_args[5].i = (jint)((inq_info->dev_class[0] & 0xff)
| ((inq_info->dev_class[1] & 0xff) << 8) | ((inq_info->dev_class[2] &
0xff) << 16));
                printf("Apunto de crear un nuevo objeto\n");

///AQUI ES DONDE PETA VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
                info_dev = env->NewObjectA(iid_cls, iid_con_id, iid_args);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

                env->CallVoidMethod(agent, ii_add_id, info_dev);

                inq_info++;
        }
        printf("Objetos creados!!!!\n");
        free(inq_info_bak);
        return true;
}

Pues eso, si alguien tiene experiencia en tipos básicos de C entre
archs y se le ocurre algo que me avise. :)
-- 
Arkaitz


Más información sobre la lista de distribución eside-ghost