C ++ - создание объекта параметров и JNA - PullRequest
0 голосов
/ 02 марта 2011

Отказ от ответственности: Я почти все игнорирую в C ++, поэтому я надеюсь, что не буду говорить глупости здесь, если я, пожалуйста, не стесняйтесь поправлять меня.

КакJava-разработчик, когда я хочу создать новый объект, я использую метод конструктора, который будет выделять этот объект в памяти и возвращать его дескриптор для меня, и я буду хранить этот дескриптор в переменной, я делаю это так.

Foo o = new Foo();

Но в C ++ мне дали понять, что, несмотря на то, что это возможно,

Foo createFoo(){
    Foo f;
    f.doSomething();
    return f;
}

// ...

Foo f = createFoo();

Я также могу определить дескриптор самостоятельно, а затемвызовите на нем инициализатор, который выделит память и свяжет с ним дескриптор, например:

void initializeFoo(Foo **f){
    f.doSomething();
    return;
}

// ...

Foo f;
initializeFoo(&f);

Итак, мой вопрос: что произойдет, когда мы захотим использовать эти методы C ++ в Java с JNA?

Предположим, у меня есть следующий заголовок C ++:

typedef struct Foo f;

Foo createFoo();
void initializeFoo(Foo **f);

Поскольку у меня нет никакого представления о том, что такое Foo или что содержит структура Foo, я просто собираюсьсоздайте JNA PointerType, чтобы объявить мою структуру:

public class Foo extends PointerType{

    public Foo(Pointer address) {
        super(address);
    }
    public Foo() {
        super();
    }
}

Использование метода createFoo также должно быть довольно простым:

public class TestFoo{
    static{
        System.loadLibrary("foolib");
    }

    public static void main(String[] args){
        FooLib lib = (FooLib)Native.loadLibrary("foolib", FooLib.class);

        Foo f = lib.createFoo();
    }

Верно?

Но мой вопрос, как я могу использовать функцию initializeFoo ???Я полагаю, мне нужно было бы создать указатель и передать его функции, но как мне создать ненулевой указатель в JNA?Я попробовал следующий код, но это приводит к EXCEPTION_ACCESS_VIOLATION.

public class TestFoo{
    static{
        System.loadLibrary("foolib");
    }

    public static void main(String[] args){
        FooLib lib = (FooLib)Native.loadLibrary("foolib", FooLib.class);

        Foo f = new Foo();
        lib.initializeFoo(f); // EXCEPTION_ACCESS_VIOLATION
        lib.initializeFoo(f.getPointer()); // EXCEPTION_ACCESS_VIOLATION
    }

Есть идеи?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 02 марта 2011
Foo f;
initializeFoo(&f);

initializeFoo() не "выделяет память и не связывает дескриптор" для f, как вы говорите. Foo f; создает f и размещает его в памяти. initializeFoo() может сделать что-то вроде присвоения значений свойствам элемента f и т. П., А также создать другой объект Foo и назначить его для f, но он не будет делать то, что вы говорите.

С другой стороны,

Foo *f;
f = new Foo();

объявляет указатель Foo. new выделяет память и создает объект Foo, а также назначает расположение в памяти для f (указатель можно рассматривать как целое число, содержащее адрес).

Я думаю, что вы хотите узнать больше о C ++ и указателях, прежде чем идти дальше.

1 голос
/ 02 марта 2011

Поскольку я понятия не имею, что такое Foo или что содержит структура Foo, я просто собираюсь создать JNA PointerType для объявления моей структуры

Это делает невозможным выделение памяти для Foo, так как вы должны знать, сколько памяти вам нужно выделить. Для структур c jna нужен класс java, отражающий структуру или, если вы хотя бы знаете его размер, вы можете попробовать использовать класс Memory, у которого ctor принимает аргумент размера.

Для структур и классов c ++, использующих такие функции c ++, как наследование, это не удается, поскольку требуемая память и компоновка зависят от компилятора и включенных оптимизаций.

...