2015-03-25 7 views
4

Часто пользователи Clojure хотят быть как можно более ленивыми и задерживать создание классов и объектов. В том же духе, если я хочу вызвать встроенную функцию, которая разрешена во время выполнения изнутри Java, я могу использовать com.sun.jna.Function.getFunction("foolibrary", "foofuncname"), который возвращает com.sun.jna.Function, который может быть invoked.В Java и с помощью Bridj, как вы можете динамически вызывать любую собственную функцию?

В Clojure это выглядит следующим образом:

(let [f (com.sun.jna.Function/getFunction "c" "printf")] 
    (.invoke f Integer (to-array ["Hello World"]))) 

BridJ, с другой стороны, предлагает привлекательные преимущества в производительности и утверждал, проще API, однако, до сих пор мне не ясно, как использовать BridJ, чтобы сделать что-то аналогично примеру JNA, связанному с исполнением. Может ли кто-нибудь продемонстрировать, как? Кроме того, если это возможно, существуют ли какие-либо штрафы за производительность при таком подходе? В противном случае, он кажется, что генерация исходного файла Java раньше времени является единственным решением. Буду признателен, если кто-то сможет это подтвердить.

ответ

1

Edit:

После лучшего понимания вопроса & с упором на «динамически» (без предварительной компиляции), я до сих пор стесняются утверждать «это невозможно» («невозможно» очень сильное слово/смысл ... как «всегда»/«никогда»), но я точно очень уверен, что это не стандартная процедура BridJ. Я могу думать о динамическом решении с Bridj, но это, вероятно, будет зависеть от «JNAerator», и это, в свою очередь, будет зависеть от «JNA» (ваша начальная позиция).

оригинальный ответ, описывая «стандартную процедуру» для «динамически вызывать любую внешнюю функцию с BridJ» (включая генерацию кода):

Согласно https://code.google.com/p/bridj/ и https://code.google.com/p/bridj/wiki/FAQ, вам придется:

  1. Настройте проект bridJ (зависимости java project + bridJ)
  2. Запустите the JNAerator (с возможностью выхода bridJ) против ваших библиотек. Это создаст файлы Java, которые будут служить «заглушками/делегатами» для экспортированных функций.
  3. Эти «заглушки» могут ссылаться/использоваться вашим кодом java и (должны) ссылаться на ваши библиотеки.

Образец взят из "их Quickstart":

Оригинал C++ код:

/// exported in test.dll/libtest.so/libtest.dylib 
class MyClass { 
    public: 
     MyClass(); 
     ~MyClass(); 
     virtual void virtualMethod(int i, float f); 
     void normalMethod(int i); 
}; 
void getSomeCount(int* countOut); 
... 
void test() { 
    int count; 
    getSomeCount(&count); 
    MyClass t; 
    t.virtualMethod(count, 0.5f); 
} 

Перевод + связывание с BridJ:

(это сгенерированный код Java)

import org.bridj.*;  // C interop and core classes 
import org.bridj.ann.*; // annotations 
import org.bridj.cpp.*; // C++ runtime 
import static org.bridj.Pointer.*; // pointer factories such as allocateInt(), pointerTo(java.nio.Buffer), etc... 

@Library("test") 
public class TestLibrary { 
    static { 
     BridJ.register(); // binds all native methods in this class and its subclasses 
    } 
    public static class MyClass extends CPPObject { 
     @Virtual(0) // says virtualMethod is the first virtual method 
     public native void virtualMethod(int i); 
     public native void normalMethod(int i); 
    }; 
    public static native void getSomeCount(Pointer<Integer> countOut); 

    public static void test() { 
     Pointer<Integer> pCount = allocateInt(); 
     getSomeCount(pCount); 
     MyClass t = new MyClass(); 
     t.virtualMethod(pCount.get(), 0.5f); 
    } 
} 

Надеюсь, это поможет!

+1

Я думаю, что я не был достаточно ясен о своем вопросе, и я обновил формулировку. Я спрашиваю, возможно ли время выполнения/отсрочка привязки. Ваш ответ требует генерации кода Java, который должен быть скомпилирован и загружен вовремя, а не как раз вовремя. – bmillare

+0

ОК, я думаю, что я поняла, но я также опасаюсь, что BridJ не будет отображаться. (никоим образом не вокруг JNAerator ... определенно не в пределах 2-3 строк!) Я бы придерживался вашего текущего продукта, который также является «не стандартным java». но (ранее) это https://java.net/projects/jna/ и в настоящее время это https://github.com/twall/jna/ project/product. – xerx593

+0

Ответ, в котором говорится, что это невозможно, остается верным ответом. Я дам вам очки, если в ближайшие оставшиеся часы ничего не появится. – bmillare

 Смежные вопросы

  • Нет связанных вопросов^_^