Ok, mozda vam malo koda pomogne (oni koji ne znaju javu nece imati problema posto java ne radi nista fundamentalno - trebalo bi da java na promptu odstampa tekst "See the mouse?Clickl it!" i da ceka da joj C posalje signal da se desio dogadjaj-levi klik misem,zatim da odstampa "Thanks for clicking" i "Goodbye"; C kreira thread koji se kaci za javu i kreira prozor koji ce da hvata dogadjaje, kad uhvati dogadjaj salje javi signal, odnosno poziva njen metod da napise "Thanks.."):
Code:
/****************Dogadjajava.java******************/
import java.util.*;
public class Dogadjajava
{
private int handler = 0;
private Vector listeners = new Vector();
private native void nativeEnable() throws UnsatisfiedLinkError;
private native void nativeDisable() throws UnsatisfiedLinkError;
/**
* Loads the JNI library, if available.
*/
public static boolean initialize()
{
// Load JNI library
try
{
System.load( "C:\\C++\\dogadjajC\\Debug\\dogadjajC.dll" );
System.out.println("J: Dynamic Library Loaded\n");
}
catch( UnsatisfiedLinkError x )
{
return false;
}
return true;
}
/**
* Creates a window.
**/
public Dogadjajava()
{
super();
}
/**
* Enables the window for events
*/
public void show()
{
try
{
nativeEnable();
}
catch( UnsatisfiedLinkError x )
{
}
}
/**
* Hides the window for events
*/
public void hide()
{
try
{
nativeDisable();
}
catch( UnsatisfiedLinkError x )
{
}
}
/**
* Notifies all listeners that the desktop indicator was clicked.
**/
public void fireClicked()
{
Vector listenersClone = (Vector) listeners.clone();
DogadjajavaListener listener;
for( Enumeration e = listenersClone.elements(); e.hasMoreElements(); )
{
listener = (DogadjajavaListener) e.nextElement();
listener.onDogadjajClicked( this );
}
System.out.println("Thanks for clicking!\n");
}
public void addDogadjajavaListener( DogadjajavaListener listener )
{
listeners.addElement( listener );
}
public void removeDogadjajavaListener( DogadjajavaListener listener )
{
listeners.removeElement( listener );
}
}
Code:
/*******************DogadjajavaListener.java******************/
public interface DogadjajavaListener
{
/**
* Called when something is clicked.
**/
void onDogadjajClicked( Dogadjajava source );
}
Code:
/*******************DogadjajavaTest.java********************/
public class DogadjajavaTest implements DogadjajavaListener
{
static DogadjajavaTest listener;
static public void main( String args[] )
{
// Initialize JNI extension
if( !Dogadjajava.initialize() )
{
System.err.println( "Either you are not on Windows, or there is a problem with the dogadjajC library!" );
return;
}
Dogadjajava dogadjaj = new Dogadjajava();
listener = new DogadjajavaTest();
dogadjaj.addDogadjajavaListener( listener );
dogadjaj.show();
// Instructions
System.err.println( "See the mouse? Click it!" );
// Wait for the bitter end
try
{
synchronized( listener )
{
listener.wait();
}
}
catch( InterruptedException x )
{
}
// Time to die
dogadjaj.removeDogadjajavaListener( listener );
dogadjaj.hide();
System.err.println( "Goodbye!" );
}
public void onDogadjajClicked( Dogadjajava source )
{
synchronized( listener )
{
listener.notifyAll();
}
}
}
Code:
/**********************dogadjajC.cpp********************/
#include "stdafx.h"
#include "Dogadjajava.h"
#include "DogadjajCHandler.h"
HINSTANCE g_instance = NULL;
BOOL WINAPI DllMain
(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
)
{
switch( fdwReason )
{
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
case DLL_PROCESS_ATTACH:
g_instance = hinstDLL;
break;
}
return TRUE;
}
extern "C"
/*
* Class: Dogadjajava
* Method: nativeDisable
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Dogadjajava_nativeDisable
(JNIEnv *env, jobject object)
{
// Get handler
DogadjajCHandler *l_handler = DogadjajCHandler::extract( env, object );
// Disable it
if( l_handler )
l_handler->disable();
}
extern "C"
/*
* Class: Dogadjajava
* Method: nativeEnable
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Dogadjajava_nativeEnable
(JNIEnv *env, jobject object)
{
// Get handler
DogadjajCHandler *l_handler = DogadjajCHandler::extract( env, object );
// Create our handler
l_handler = new DogadjajCHandler( env, object );
// Enable it
if( l_handler )
l_handler->enable( env );
}
Code:
/*******************dogadjajCHandler.cpp********************/
#include "stdafx.h"
#include "DogadjajCHandler.h"
#include "DogadjajCThread.h"
#define WM_MOUSE_CLICK (WM_USER+1)
DogadjajCHandler *DogadjajCHandler::extract( JNIEnv *env, jobject object )
{
// Get field ID
jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( object ), "handler", "I" );
// Get field
DogadjajCHandler *l_handler = (DogadjajCHandler *) env->GetIntField( object, l_handlerId );
return l_handler;
}
DogadjajCHandler::DogadjajCHandler( JNIEnv *env, jobject object)
{
m_window = NULL;
// Reference object
m_object = env->NewGlobalRef( object );
// Get method ID
m_fireClicked = env->GetMethodID( env->GetObjectClass( m_object ), "fireClicked", "()V" );
// Get field ID
jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( m_object ), "handler", "I" );
// Set field
env->SetIntField( m_object, l_handlerId, (jint) this );
}
DogadjajCHandler::~DogadjajCHandler()
{
// Get field ID
jfieldID l_handlerId = g_DogadjajCThread.m_env->GetFieldID( g_DogadjajCThread.m_env->GetObjectClass( m_object ), "handler", "I" );
// Set field
g_DogadjajCThread.m_env->SetIntField( m_object, l_handlerId, 0 );
// Release our reference
g_DogadjajCThread.m_env->DeleteGlobalRef( m_object );
// Destroy window
DestroyWindow( m_window );
}
void DogadjajCHandler::enable( JNIEnv *env )
{
g_DogadjajCThread.MakeSureThreadIsUp( env );
while( !PostThreadMessage( g_DogadjajCThread, WM_CLICK, enableCode, (LPARAM) this ) )
Sleep( 1000 );
}
void DogadjajCHandler::doEnable()
{
// Register window class
WNDCLASSEX l_Class;
l_Class.cbSize = sizeof( l_Class );
l_Class.style = 0;
l_Class.lpszClassName = TEXT( "DogadjajCHandlerClass" );
l_Class.lpfnWndProc = WndProc;
l_Class.hbrBackground = NULL;
l_Class.hCursor = NULL;
l_Class.hIcon = NULL;
l_Class.hIconSm = NULL;
l_Class.lpszMenuName = NULL;
l_Class.cbClsExtra = 0;
l_Class.cbWndExtra = 0;
if( !RegisterClassEx( &l_Class ) )
return;
// Create window
m_window = CreateWindow
(
TEXT( "DogadjajCHandlerClass" ),
TEXT( "DogadjajCHandler" ),
WS_POPUP,
0, 0, 0, 0,
NULL,
NULL,
0,
NULL
);
if( !m_window )
return;
// Set this pointer
SetWindowLong( m_window, GWL_USERDATA, (LONG) this );
}
void DogadjajCHandler::disable()
{
PostThreadMessage( g_DogadjajCThread, WM_CLICK, disableCode, (LPARAM) this );
}
void DogadjajCHandler::fireClicked()
{
g_DogadjajCThread.m_env->CallVoidMethod( m_object, m_fireClicked );
}
LRESULT CALLBACK DogadjajCHandler::WndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam )
{
// Check for our special notification message
if( ( uMessage == WM_MOUSE_CLICK ) && ( INT(lParam) == WM_LBUTTONDOWN ) )
{
DogadjajCHandler *l_this = (DogadjajCHandler *) GetWindowLong( hWnd, GWL_USERDATA );
// Click!
l_this->fireClicked();
return 0;
}
else
return DefWindowProc( hWnd, uMessage, wParam, lParam );
}
Code:
/********************dogadjajCThread.cpp*********************/
#include "stdafx.h"
#include "DogadjajCThread.h"
#include "DogadjajCHandler.h"
DogadjajCThread g_DogadjajCThread;
DogadjajCThread::DogadjajCThread()
{
m_env = NULL;
m_thread = 0;
m_vm = NULL;
m_handlerCount = 0;
}
void DogadjajCThread::MakeSureThreadIsUp( JNIEnv *env )
{
if( !m_thread )
{
// Get VM
env->GetJavaVM( &m_vm );
// Start "native" thread
CreateThread
(
NULL,
0,
ThreadProc,
this,
0,
&m_thread
);
}
}
DogadjajCThread::operator DWORD ()
{
return m_thread;
}
DWORD WINAPI DogadjajCThread::ThreadProc( LPVOID lpParameter )
{
DogadjajCThread *l_this = (DogadjajCThread *) lpParameter;
// Attach the thread to the VM
l_this->m_vm->AttachCurrentThread( (void**) &l_this->m_env, NULL );
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
if( msg.message == WM_CLICK )
{
// Extract handler
DogadjajCHandler *l_handler = (DogadjajCHandler*) msg.lParam;
switch( msg.wParam )
{
case DogadjajCHandler::enableCode:
l_this->m_handlerCount++;
l_handler->doEnable();
break;
case DogadjajCHandler::disableCode:
// Destroy it!
delete l_handler;
// No more handlers?
if( !--l_this->m_handlerCount )
{
l_this->m_thread = 0;
// Detach thread from VM
l_this->m_vm->DetachCurrentThread();
// Time to die
ExitThread( 0 );
}
break;
}
}
else
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
// Detach thread from VM
l_this->m_vm->DetachCurrentThread();
return 0;
}
Kod je napisan na osnovu primera koji dobro radi. Lepo se kompajlira, ali nece da radi. Odnosno radi donekle, odstampa
See the mouse? Click it!
I dalje nece da mrdne, ne reaguje na klikove i nista drugo, vec moram na silu da ga ubijem. Ako vas ne mrzi da citate kod, pomozite da otkrijem gde se zaglavljujem!