I had absolutely no clue where to post this but I figured since it crashes on the C++ side, I'd ask here.

I have the following code:

Java side (Loads My C++ DLL just fine.. Passes it a ByteBuffer so that I can write to that):

import java.io.IOException;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.nio.ByteBuffer;

public class Library
{   
    static{System.loadLibrary("TestDLL");}
    static native void GetGLBuffer(ByteBuffer Buffer);

    public static void main(String[] args) {
        int BitsPerPixel = 32, Width = 344, Height = 336;
        int IntSize = ((Width * BitsPerPixel + 31) / 32) * Height;
        int ByteSize = IntSize * 4;

        ByteBuffer Buffer = ByteBuffer.allocateDirect(ByteSize);
        GetGLBuffer(Buffer);                                      //Give C++/DLL the byte buffer.
        //Frame F = new Frame("Testing Buffer", Buffer.array());
    }
}

On the C++ Side I have (Load a bitmap, get the array of pixels from it.. write that array to the Java ByteBuffer):

#include "Library.h"

EXTERN_C void __stdcall Dobitmap(std::vector<unsigned char>& Data, int &Width, int &Height, int &Size)
{
    int Bpp = 24;

    Bitmap Foo("C:/Users/Brandon/Desktop/Untitled.bmp");
    std::vector<RGB> Pixels = Foo.Foo();

    Data.clear();
    Data.resize(Foo.Size());
    unsigned char* BuffPos = &Data[0];

    for (int I = 0; I < Foo.Height(); ++I)
    {
        for (int J = 0; J < Foo.Width(); ++J)
        {
            *(BuffPos++) = Pixels[(Foo.Height() - 1 - I) * Foo.Width() + J].RGBA.B;
            *(BuffPos++) = Pixels[(Foo.Height() - 1 - I) * Foo.Width() + J].RGBA.G;
            *(BuffPos++) = Pixels[(Foo.Height() - 1 - I) * Foo.Width() + J].RGBA.R;

            if (Bpp > 24)
                *(BuffPos++) = Pixels[(Foo.Height() - 1 - I) * Foo.Width() + J].RGBA.A;
        }
        if(Bpp == 24)
            BuffPos += Foo.Width() % 4;
    }
    Size = Foo.Size();
    Width = Foo.Width();
    Height = Foo.Height();
}

JNIEXPORT void JNICALL Java_Library_GetGLBuffer(JNIEnv *env, jclass cls, jobject buffer)
{
    std::vector<unsigned char> TEMP;
    int Width = 0, Height = 0, Size = 0;
    Dobitmap(TEMP, Width, Height, Size);

    Bitmap K(TEMP, Width, Height, 24);
    K.Save("C:/users/brandon/desktop/Footest.bmp"); //Works just fine!

    void* bb = env->GetDirectBufferAddress(buffer);  //Crashes right here.. No clue why :S
}

But the above crashes! It saves my bitmap back to the desktop so I know it's working just fine up to that point. If I comment out the void* bb = env->GetDirectBufferAddres(buffer);

It works perfectly. Now here's another problem. If I comment out the bitmap code and uncomment the void* bb.... it works just fine. The problem is when I have BOTH of them! Why? What am I doing wrong?

Recommended Answers

All 4 Replies

line 18: can't do that because there is no memory allocated for the vector.

Data.push_back(Pixels[(Foo.Height() - 1 - I) * Foo.Width() + J].RGBA.B);

If you can calculate the size needed beforehand, then call Data.Resize(X) to allocate all the memory at one time, then I think the rest of your program will work as written.

:S What do you mean it can't do that? Data.resize(Foo.Size()); is already there?

I found the problem but I cannot solve it.. if I declare variables within that JNI function, it crashes.. If I don't, it works just fine. Is there a way around this? The following was my testing solution which I don't want at all.. Nevertheless, it works but for all the wrong reasons and that means I cannot assign to the pointer.

Also I tried what you said, it still crashes.

#include "Library.h"

void NothingFunction()
{
    std::vector<unsigned char> TEMP;
    int Width = 0, Height = 0, Size = 0;
    DoBitmap(TEMP, Width, Height, Size);

    Bitmap K(TEMP, Width, Height, 24);
    K.Save("C:/users/brandon/desktop/Footest.bmp");
}

JNIEXPORT void JNICALL Java_library_Library_GetGLBuffer(JNIEnv *env, jclass cls, jobject buffer)
{
    /* The following crashes it..
    unsigned char* bb = (unsigned char*)env->GetDirectBufferAddress(buffer);
    NothingFunction();  
    */

    //But if I switch the order of the calls.. it works (Also I cannot declare variables within here.. it will crash):
    NothingFunction();
    unsigned char* bb = (unsigned char*)env->GetDirectBufferAddress(buffer);
}

Any way around the above?

Similar to that. I had to go to the Java folder, copy the JNI.h, JNI_MD.h (Machine dependent) to my project and compile with a .def file.

After that, it stopped crashing =] Thanx for try though :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.