I have 2 very similar C functions being called fro

2019-09-08 17:49发布

问题:

Basically I have 2 implementations of a C function "encrypt" which I call from python using ctypes and java using JNI. I've been told to take the two dynamic libraries that were used for java and python, and combine them into a static library that can be called from both. To clarify, here's the C function implementation for java using 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);
}

So the function takes in a byte array and increments each byte by 1 then returns each element of the new byte array. Here's the java side:

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);
    }
}

The python implementation of the C function is the exact same, just not using all that JNI syntax:

#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]);
    }
}

And the python side:

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)

As you can see, the C function for python and java do the exact same thing (few minor differences). They take in a byte array, increment each byte by 1, and print each incremented byte. I just need to combine these two C libraries and combine them into a single static library which can be accessed from both python AND java. Is this possible? Thanks.

回答1:

You can call the python version from the java one. This avoids the duplicate code. You’ll still have to do the to/from JNI marshalling though:

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);
}