Передать InputStream через код JNA в C в качестве указателя файла

У меня есть DLL, написанная на C (которую я не могу редактировать), которая имеет некоторый прототип функции, который выглядит как

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

Я хотел бы создать интерфейс JNA для DLL, и неясно, что мне нужно передать для аргумента FILE *bar. Я предполагаю, что мне нужно передать InputStream (что я предпочитаю), но литература JNA кажется скудной по этому вопросу.

Как будет выглядеть интерфейс Java? и что мне действительно нужно передать foo?

Редактировать: foo предполагает, что bar является результатом fopen и вызывает такие операции, как fscanf.

Редактировать 2: В конце концов, у меня есть строка на Java, которую мне нужно прочитать на C, как если бы это был файл (что может быть совсем другим вопросом). В идеале я бы хотел избежать записи файла, поэтому преобразование InputStream в указатель файла C так желательно (и, очевидно, довольно сложно).


person Mark Elliot    schedule 26.08.2009    source источник


Ответы (2)


Я не верю, что вы можете это сделать - у вас нет простого способа получить доступ к внутренностям экземпляра InputStream, и даже FileInputStream, скорее всего, не будет реализован поверх stdio FILE *. Чтобы увидеть, каким должен быть ваш интерфейс Java, вам нужно опубликовать дополнительную информацию о функции foo — что она делает и как вы ее используете.

Если вас не волнует, что на самом деле делает FILE *, вы можете написать код с помощью JNA для вызова fopen, передав имя файла и режим открытия, и передать результат как непрозрачное значение через foo, например (псевдокод):

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

Обновление: если вам нужна строка, содержащая данные, которые вам нужно обрабатывать, как если бы они были в файле, я думаю, вам не повезло. К сожалению, стандартная библиотека C не построена на основе потоковой абстракции, а это означает, что вы вряд ли сможете достичь того, чего хотите, если не сможете открыть то, что выглядит как имя файла, но ведет к вашим строковым данным; однако будет гораздо проще стиснуть зубы и сохранить строку во временный файл, а затем открыть его с помощью fopen :-(

person Vinay Sajip    schedule 26.08.2009
comment
см. исходный вопрос для уточнения функциональности foo - хотя я подозреваю, что поведение foo в основном не имеет значения. - person Mark Elliot; 27.08.2009
comment
Справедливо, полагаю, я все еще не даю вам достаточно информации. В конце концов, у меня есть строка на Java, которую мне нужно прочитать, как если бы это был файл на C (что может быть совсем другим вопросом). В идеале я хотел бы избежать записи файла. - person Mark Elliot; 27.08.2009

В системах POSIX вы можете сделать это с помощью конвейера, если строка не слишком длинная (к сожалению, "слишком длинная" зависит от характеристик операционной системы, но не менее 512 байт):

#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;
}
person caf    schedule 27.08.2009