Problema usando JNI para acessar um método da dll que salva um buffer de imagem em um arquivo.
DLL (utilizando opencv):
EXTERN_C __declspec(dllexport) int SaveImg(char * p_BUFFER,int p_dimensionXFrame,int p_dimensionYFrame,int p_nChannels,int p_colorDepth,char * p_path);
int SaveImg(char * p_BUFFER,int p_dimensionXFrame,int p_dimensionYFrame,int p_nChannels,int p_colorDepth,char * p_path)
{
IplImage * v_frame;
v_frame = cvCreateImage( cvSize(p_dimensionXFrame,p_dimensionXFrame),p_colorDepth,p_nChannels );
cvReleaseImageData( v_frame );
cvCreateImageData( v_frame );
CopyMemory(v_frame->imageData,p_BUFFER,p_dimensionXFrame*p_dimensionYFrame);
cvSaveImage(p_path,v_frame,0);
cvReleaseImage(&v_frame);
return 1;
}
Bridge que faz JNI:
HINSTANCE HInst; // Handle da dll ISMeasures
extern "C"
{
JNIEXPORT jint JNICALL Java_Imagem_SaveImg (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jstring);
}
typedef int __stdcall (*TToMovie) (int codec, BYTE* buffer, int nFrames, int x, int y, int nChannels, int depth, int fps, char* path, int xVideo, int yVideo);
TSaveImg SaveImg = NULL;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
int ret = 0;
if (reason == DLL_PROCESS_ATTACH)
{
HInst = LoadLibrary("ToAvi.dll");
if (HInst == NULL)
{
return 0;
}
else
{
SaveImg = (TSaveImg) GetProcAddress (HInst, "SaveImg");
if (SaveImg)
return 1;
return 0;
}
}
if (reason == DLL_PROCESS_DETACH)
{
if (HInst != NULL)
ret = FreeLibrary(HInst);
}
return ret;
}
JNIEXPORT jint JNICALL Java_Imagem_SaveImg (JNIEnv *env, jobject, jbyteArray buffer, jint x, jint y, jint nChannels, jint depth, jstring path)
{
int valorRet = -1;//erro
jbyte *vals;
char *pathArquivo;
if (buffer != NULL)
{
vals = env->GetByteArrayElements(buffer,0);
pathArquivo = (char*) env->GetStringUTFChars (path,0);
valorRet = SaveImg(vals,x,y,nChannels,depth,pathArquivo);
env->ReleaseStringUTFChars(path,pathArquivo);
env->ReleaseByteArrayElements(buffer,vals,JNI_ABORT);
}
return valorRet;
}
Classe imagem:
public class Imagem {
public native int SaveImg(byte buffer[], int x, int y, int nChannels, int depth, String path);
static
{
System.loadLibrary("ToAviBridge");
}
}
Chamada do botão que salva a imagem utilizando a DLL:
private void salvarImagem()
{
File diretorio = new File ("c:\\convertido\\");
if (diretorio.exists() == false)
diretorio.mkdir();
String path = diretorio.getCanonicalPath()+"\\Salva.JPG";
Raster raster = imagemPrincipal.getPixels().getFrameBuffer(imagemPrincipal.getFrameAtual()).getData();//retorna de um BufferedImage
int []vetPixels = raster.getPixels(0, 0, 1024, 1024, (int[])null);
byte[] vetByte = new byte[1024*1024];
for (int i=0; i<1024*1024; i++)
vetByte[i] = (byte) vetPixels[i];
int retornoConv = imagem.SaveImg(vetByte, //buffer
1024,//x
1024, //y
1, //nChannels
8,//depth
path);//path
System.out.println(retornoConv);
}
O problema é que a JVM cai antes de escrever o valor da variavel retornoConv na funcao salvarImagem. Porém, chega a gravar o arquivo, alguns printfs nas funções da bridge e da dll mostram que os métodos são inteiramente executados, o problema é o crash da JVM derrubando o sistema, alguma dica?