Crash da JVM

2 respostas
U

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?

2 Respostas

J

esse mapeamento deve estar com problema. Existe um mapeamento muito bom da opencv para java que é esse. O problema é que tem uma perda considerável de desempenho(bastante mesmo). Considere usar c++ no lugar de java, porque no final das contas seria mais fácil.

http://code.google.com/p/javacv/
http://code.google.com/p/javacv/wiki/SpeedComparisons

U

Resolvido, era problema de diretivas de compilação no Builder C++

Criado 31 de janeiro de 2011
Ultima resposta 31 de jan. de 2011
Respostas 2
Participantes 2