Java application that calls Windows API methods

S

Si

I currently have a simple MFC C++ dialog program that uses the Windows API
SendMessage() method to send a message to another third-party application
(call this "Application X") and I want to recreate that program in Java. The
program contains some fairly complicated stuff that handles the
SendMessage() calls. It also uses the WindowProc() method to handle the
response message sent back from the Application X.

I think I have two options to allow me to achieve my goal:

1) Re-write the applicaton in Java and compile my C++ message handling code
into a DLL file, then call those methods in the DLL from the Java
application using JNI. This has the advantage that I already have the
message handling code written in C++.

2) Re-write the application enitrely in Java and do all the message sending
Windows API stuff directly in Java. This may be a more stable long-term
solution but I'm not entirely sure whether it is possible or how it is done.

Does anyone have any opinions on how I should go ahead and do this? Should I
use option 1 or 2? Or any other approach I should consider? Any recommended
reading material on this area?

One other thing that concerns me is the WindowProc() method - does this work
in a DLL (i.e. how do Windows DLLs send messages to and receive messages
from other applications?)?

Thanks in advance.
 
A

Alf P. Steinbach

* Si:
I currently have a simple MFC C++ dialog program that uses the Windows API
SendMessage() method to send a message to another third-party application
(call this "Application X")

It's generally not a good idea to send window messages across process
boundaries. Instead consider using a mailslot, a COM object, even raw
RPC, a socket, or in the other direction, SOAP, or whatever. I'd use a
mailslot or, if more complicated data than simple text is required, a
COM object, since that's simple and efficient within a single machine.

and I want to recreate that program in Java. The
program contains some fairly complicated stuff that handles the
SendMessage() calls. It also uses the WindowProc() method to handle the
response message sent back from the Application X.

A response message? Then a COM object seems to be indicated, that takes
care of synchronization and marshaling, almost automatically. I.e.,
make that "Application X" a COM object server.

I think I have two options to allow me to achieve my goal:

1) Re-write the applicaton in Java and compile my C++ message handling code
into a DLL file, then call those methods in the DLL from the Java
application using JNI. This has the advantage that I already have the
message handling code written in C++.

Yes, you can do that.

2) Re-write the application enitrely in Java and do all the message sending
Windows API stuff directly in Java. This may be a more stable long-term
solution but I'm not entirely sure whether it is possible or how it is done.

AFAIK it's not possible with Sun's Java, and the days of Microsofts
what-was-it-called version of Java is over. But you can use a COM
bridge (more commonly called an ActiveX bridge) to use a COM object from
Java. Only note that at least as of a few years ago, Sun's ActiveX
bridge had lots of bugs and a tendency to eat memory.

Does anyone have any opinions on how I should go ahead and do this? Should I
use option 1 or 2? Or any other approach I should consider? Any recommended
reading material on this area?

COM object. See above. Or, use one of the other solutions mentioned above.

One other thing that concerns me is the WindowProc() method - does this work
in a DLL (i.e. how do Windows DLLs send messages to and receive messages
from other applications?)?

A DLL simply becomes part of the program it's loaded in; it's no
different from other code in that program, except for initialization and
uninitialization, which can be somewhat difficult to do correctly.
 
S

Si

Alf P. Steinbach said:
* Si:

It's generally not a good idea to send window messages across process
boundaries. Instead consider using a mailslot, a COM object, even raw
RPC, a socket, or in the other direction, SOAP, or whatever. I'd use a
mailslot or, if more complicated data than simple text is required, a COM
object, since that's simple and efficient within a single machine.

Unfortunately I *have* to communicate with Application X using SendMessage()
as it provides a text-based API which uses this method.
A response message? Then a COM object seems to be indicated, that takes
care of synchronization and marshaling, almost automatically. I.e., make
that "Application X" a COM object server.

Sorry I don't know what you mean here. I can't make any changes to App X at
all.
Yes, you can do that.

.... and SendMessage() and WindowProc() will both work correctly to send
messages to and from the DLL to App X?
AFAIK it's not possible with Sun's Java, and the days of Microsofts
what-was-it-called version of Java is over. But you can use a COM bridge
(more commonly called an ActiveX bridge) to use a COM object from Java.
Only note that at least as of a few years ago, Sun's ActiveX bridge had
lots of bugs and a tendency to eat memory.



COM object. See above. Or, use one of the other solutions mentioned
above.

What advantage would creating a COM object have over writing a DLL and
loading it in my Java program? Can I use my existing C++ code with the COM
object? What is the difference between a COM object and a DLL?
A DLL simply becomes part of the program it's loaded in; it's no different
from other code in that program, except for initialization and
uninitialization, which can be somewhat difficult to do correctly.

In this case the DLL will be part of javaw.exe and will function correctly
within that I presume...

Thanks for the suggestions.
 
A

Alf P. Steinbach

* Si:
* Alf P. Steinbach:

Unfortunately I *have* to communicate with Application X using SendMessage()
as it provides a text-based API which uses this method.

Ah, "third-party". Sorry I didn't notice.


[snip]
... and SendMessage() and WindowProc() will both work correctly to send
messages to and from the DLL to App X?

SendMessage will, certainly. As for WindowProc, that's presumably your
own window procedure (there's no Windows API function called
WindowProc). Now that's a different kettle of fish altogether, because
a window procedure is called for messages to the window it's serving.

If you have the option of informing Application X which window handle it
should send its responses back to, then the simplest is probably to
create an invisible receiver window in the DLL code, but I haven't done
that: it's possible that you'll end up with some thread issue (the
window needs to be created on a thread with a message loop).

Otherwise you may have to intercept window messages for the Java-side
main window, and that's a bit complicated, but as I recall Sun has a
special JNI-thing called someting-AWT or AWT-something (that's not the
AWT but a JNI binding for AWT) that would help, and otherwise, but you'd
probably not ask here if you knew that, you can subclass the Java main
window from the C++ code. On second thoughts, that's probably the
simplest. _If_ you have have to use the application's main window.


[snip]
What advantage would creating a COM object have over writing a DLL and
loading it in my Java program?

As long you _have_ to send and receive window messages using a third
party protocol, not much. It can free you from synchronization issues,
but that can also be done very simply in Java code. Please just forget
that I mentioned COM -- I didn't see that you have the constraint of
absolutely having to use window messages.

Can I use my existing C++ code with the COM object?

Probably, but that's impossible to know.

What is the difference between a COM object and a DLL?

A DLL is a library of functions and variables used directly by your
program. A COM object is a collection of functions (grouped into
intefaces), that operate on a state you cannot access directly. A COM
object can be implemented in terms of a DLL, or as an EXE, but from the
client code point of view you don't need to know how it's implemented;
you use it the same way anyhow. The COM infrastructure takes care of
marshaling your calls across process boundaries, and even across machine
boundaries (over the network), if necessary.
 
C

Chris Uppal

[x-posting removed]
I currently have a simple MFC C++ dialog program that uses the Windows API
SendMessage() method to send a message to another third-party application
(call this "Application X") and I want to recreate that program in Java.

Why ? You have working code, why re-create it in an environment that is less
well suited to implementing this kind of functionality ?

1) Re-write the applicaton in Java and compile my C++ message handling
code into a DLL file, then call those methods in the DLL from the Java
application using JNI. This has the advantage that I already have the
message handling code written in C++.

Possible. I'm no great Win32-er but I think you'll have to start a worker
thread in your DLL to communicate with the Application X. If so, then you'll
have to be careful with the threading and keep in mind which JNIEnv you are
using and which local references are valid at any time. You'll have to arrange
some way for the Java code to communicate with the worker thread. If you have
to do any JNI activity (anything that uses a JNIEnv) on that thread then don't
forget to register it with the JVM (I forget the API offhand).

2) Re-write the application enitrely in Java and do all the message
sending Windows API stuff directly in Java. This may be a more stable
long-term solution but I'm not entirely sure whether it is possible or
how it is done.

Possible, but not how I'd do it unless I were a reasonably good Win32
programmer (ie. not dependent on MFC).

Anyway, there are ways to call Win32 APIs. One is to write a very thin JNI
shim for connecting the two (which you will find easy since you are obviously
good at both Win32 and JNI or you wouldn't be considering this option ;-)
Another is to invoke the Win32 APIs directly using techniques such as those
described in chapter 9 of Sheng Liang's JNI book (downloadable free from Sun).
As far as I can tell various commercial products such as:
http://www.excelsior-usa.com/xfunction.html
http://www.jniwrapper.com/pages/jniwrapper/overview
are implementations of the same sorts of ideas (but I have not used, or even
played with, any of them).

Once again, you'll have to consider how to get a Win32 event loop implemented
in a system that doesn't really want to have one. (It is only with great
creaking and groaning that the Java graphics code in the AWT implementation
manages to talk Win32). I presume you'll have to start a new Java Thread to
run the Win32 event loop, and just /hope/ that that actually is implemented as
an OS-level thread. (Which it will be if you are using Sun JVMs, but that is
not guaranteed by any part of the Java platform spec.)

Does anyone have any opinions on how I should go ahead and do this?
Should I use option 1 or 2? Or any other approach I should consider?

One other approach that I'd consider is to retain your existing C++ program,
but adapt it to talk TCP/IP instead of having a GUI. It would act as an
intermediary between the Java code (which would only talk TCP) and application
X. Note that most of the complexity in the other two solutions comes from
communicating between two independent event loops, using an intermediary
process isolates most of that complexity.

-- chris
 
S

Si

Chris Uppal said:
[x-posting removed]
I currently have a simple MFC C++ dialog program that uses the Windows
API
SendMessage() method to send a message to another third-party application
(call this "Application X") and I want to recreate that program in Java.

Why ? You have working code, why re-create it in an environment that is
less
well suited to implementing this kind of functionality ?

Because whilst the message passing part of the program is working I'm
finding the rest of its development very slow and tedious - mainly down to
the fact that I'm not an experienced C++/Win32 programmer. I do, however,
have a fair bit of Java experience and I'm far more comfortable working with
it than C++.
Possible. I'm no great Win32-er but I think you'll have to start a worker
thread in your DLL to communicate with the Application X. If so, then
you'll
have to be careful with the threading and keep in mind which JNIEnv you
are
using and which local references are valid at any time. You'll have to
arrange
some way for the Java code to communicate with the worker thread. If you
have
to do any JNI activity (anything that uses a JNIEnv) on that thread then
don't
forget to register it with the JVM (I forget the API offhand).

Sounds like this is the best way for me.
Possible, but not how I'd do it unless I were a reasonably good Win32
programmer (ie. not dependent on MFC).

I'm dependent on MFC to be honest.
Anyway, there are ways to call Win32 APIs. One is to write a very thin
JNI
shim for connecting the two (which you will find easy since you are
obviously
good at both Win32 and JNI or you wouldn't be considering this option ;-)
Another is to invoke the Win32 APIs directly using techniques such as
those
described in chapter 9 of Sheng Liang's JNI book (downloadable free from
Sun).
As far as I can tell various commercial products such as:
http://www.excelsior-usa.com/xfunction.html
http://www.jniwrapper.com/pages/jniwrapper/overview
are implementations of the same sorts of ideas (but I have not used, or
even
played with, any of them).

Once again, you'll have to consider how to get a Win32 event loop
implemented
in a system that doesn't really want to have one. (It is only with great
creaking and groaning that the Java graphics code in the AWT
implementation
manages to talk Win32). I presume you'll have to start a new Java Thread
to
run the Win32 event loop, and just /hope/ that that actually is
implemented as
an OS-level thread. (Which it will be if you are using Sun JVMs, but that
is
not guaranteed by any part of the Java platform spec.)

Sounds pretty nasty to me.
One other approach that I'd consider is to retain your existing C++
program,
but adapt it to talk TCP/IP instead of having a GUI.

So in order for the application to run properly, I would need to have both
my modified C++ application and my new Java GUI application running at the
same time (as well as App X)?
It would act as an
intermediary between the Java code (which would only talk TCP) and
application
X. Note that most of the complexity in the other two solutions comes
from
communicating between two independent event loops, using an intermediary
process isolates most of that complexity.

So what you are saying is that the new Java GUI program will communicate
with the modified C++ program using TCP and then the C++ program will handle
App X. Responses will then also go via the modified C++ program to the Java
program. Interesting.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top