У меня есть 2 очень похожие функции C, вызываемые из python и Java. Как объединить 2 библиотеки в 1, которые можно вызвать с обоих языков?

В основном у меня есть 2 реализации функции C «encrypt», которую я вызываю из python, используя ctypes и java, используя JNI. Мне сказали взять две динамические библиотеки, которые использовались для java и python, и объединить их в статическую библиотеку, которая может быть вызвана из обоих. Чтобы уточнить, вот реализация функции C для java с помощью JNI:

#include "jniTest.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_jniTest_passBytes
  (JNIEnv *env, jclass cls, jbyteArray array) {
    unsigned char *buffer = (*env)->GetByteArrayElements(env, array, NULL);
    jsize size = (*env)->GetArrayLength(env,array);

    for(int i=0; i<size; i++){
        buffer[i] += 1;
        printf("%c",buffer[i]);
    }
    (*env)->ReleaseByteArrayElements(env, array, buffer, 0);
}

Таким образом, функция принимает в массив байтов и увеличивает каждый байт на 1, а затем возвращает каждый элемент нового массива байтов. Вот сторона java:

class jniTest{
    public static native void passBytes(byte[] bytes);
    static{
        System.loadLibrary("encrypter");
    {
    public static void main(String[] args){
        Tester tester = new Tester();
        byte[] b = "hello";
        tester.passBytes(b);
    }
}

Реализация python функции C точно такая же, просто не используя весь синтаксис JNI:

#include <stdio.h>

void encrypt(int size, unsigned char *buffer);

void encrypt(int size, unsigned char *buffer){
    for(int i=0; i < size; i++){
        buffer[i]+=1; 
        printf("%c", buffer[i]);
    }
}

И сторона питона:

import ctypes

encryptPy = ctypes.CDLL('/home/aradhak/Documents/libencrypt.so')
hello = "hello"
byteArr = bytearray(hello)
rawBytes = (ctyes_c.ubyte*len(byteArr)(*(byteArr))
encryptPy.encrypt(len(byteArr), rawBytes)

Как вы можете видеть, функция C для python и java делают то же самое (несколько незначительных различий). Они берут массив байтов, увеличивают каждый байт на 1 и печатают каждый увеличенный байт. Мне просто нужно объединить эти две библиотеки C и объединить их в одну статическую библиотеку, к которой можно получить доступ как с python, так и с java. Возможно ли это? Спасибо.

1 ответ

  1. Вы можете вызвать версию python из java one. Это позволяет избежать дублирования кода.
    Вы все равно должны сделать/от JNI маршалинга, хотя:

    void encrypt(int size, unsigned char *buffer){
        for(int i=0; i < size; i++){
            buffer[i]+=1; 
            printf("%c", buffer[i]);
        }
    }
    
    JNIEXPORT void JNICALL Java_jniTest_passBytes
      (JNIEnv *env, jclass cls, jbyteArray array) {
        unsigned char *buffer = (*env)->GetByteArrayElements(env, array, NULL);
        jsize size = (*env)->GetArrayLength(env,array);
    
        encrypt(size, buffer);
    
        (*env)->ReleaseByteArrayElements(env, array, buffer, 0);
    }