2009-08-26 7 views
4

J'ai une DLL écrit en C (que je ne peux pas modifier) ​​qui a un certain prototype de fonction qui ressemble àpasse InputStream par la JNA au code C comme un fichier pointeur

#include <stdio.h> 
void foo(FILE *bar); 

Je voudrais pour créer une interface JNA à la DLL et il n'est pas clair ce que je dois passer pour l'argument barre FILE *. Je suppose que je dois passer un InputStream (qui est ma préférence), mais la littérature JNA semble rare sur le sujet.

À quoi ressemblerait l'interface Java? et qu'est-ce que j'ai vraiment besoin de passer à foo?

Édition: foo suppose que la barre est le résultat d'un fopen et appelle des opérations comme fscanf.

Édition 2: En fin de compte, j'ai une chaîne en Java que j'ai besoin de lire en C comme s'il s'agissait d'un fichier (ce qui pourrait être une question complètement différente). Idéalement, je voudrais éviter d'écrire le fichier, c'est pourquoi la conversion d'un InputStream en un pointeur de fichier C est si souhaitable (et évidemment assez difficile).

+0

Je mis à jour ma réponse à nouveau –

Répondre

3

Je ne crois pas que vous pouvez faire cela - vous n'avez pas un moyen facile d'accéder aux internes d'une instance InputStream, et même un FileInputStream ne sera probablement pas mis en œuvre au-dessus d'un fichier stdio *. Pour voir à quoi devrait ressembler votre interface Java, vous devrez en poster plus sur la fonction foo - ce qu'elle fait et comment vous l'utilisez.

Si vous ne se soucient pas de ce que le FILE * en réalité pour, vous pouvez coder à l'aide de la JNA pour appeler fopen, en passant dans le nom du fichier et le mode ouvert, et passer le résultat comme une valeur opaque jusqu'à foo, par exemple (Pseudo-code):

path = "MyFile.txt"; 
bar = Libc.fopen(path, "r"); 
Libfoo.foo(bar); 

Mise à jour: Si vous avez besoin d'avoir une chaîne qui contient des données dont vous avez besoin traité comme si elle était dans un fichier, je pense que vous êtes hors de la chance. Malheureusement, la bibliothèque C standard n'est pas construite au-dessus d'une abstraction de flux, ce qui signifie que vous ne pourrez probablement pas obtenir ce que vous voulez, sauf si vous pouvez ouvrir ce qui ressemble à un nom de fichier mais qui conduit à vos données de chaîne; Cependant, il sera beaucoup plus facile de mordre la balle et d'enregistrer la chaîne dans un fichier temporaire, puis d'ouvrir celui-ci avec fopen :-(

+0

voir la question originale des précisions sur Foo fonctionnalité - bien que je soupçonne que le comportement de foo est la plupart du temps non pertinent –

+0

C'est juste, je suppose que je ne vous donne toujours pas assez d'informations.Enfin, j'ai une chaîne en Java que j'ai besoin de lire comme si elle était ile en C (ce qui pourrait être une question complètement différente). Idéalement, j'aimerais éviter d'écrire le fichier. –

0

Sur les systèmes POSIX, vous pouvez le faire en utilisant un tube, à condition la chaîne est pas trop long (malheureusement « trop longtemps » dépend des caractéristiques du système d'exploitation, mais est d'au moins 512 octets):.

#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 

int string_to_foo(const char *str, size_t len) 
{ 
    int pipefd[2]; 
    FILE *infile; 

    if (len > PIPE_BUF) 
    { 
     /* Error - string possibly too long */ 
     return -1; 
    } 

    if (pipe(pipefd)) 
    { 
     /* Error - pipe() failed */ 
     return -1; 
    } 

    if (write(pipefd[1], str, len) < len) 
    { 
     close(pipefd[0]); 
     close(pipefd[1]); 

     /* Error - write() failed */ 
     return -1; 
    } 

    close(pipefd[1]); 

    infile = fdopen(pipefd[0], "r"); 

    if (!infile) 
    { 
     close(pipefd[0]); 

     /* Error - fdopen() failed */ 
     return -1; 
    } 

    foo(infile); 

    fclose(infile); 

    return 0; 
} 
Questions connexes