Clever JNI solution needed  
Author Message
Michiel Konstapel





PostPosted: 2004-4-7 2:46:00 Top

java-programmer, Clever JNI solution needed On Thu, 25 Mar 2004 20:01:32 -0500, Jim Sculley
<email***@***.com> wrote:

> I'm wrapping some Java around a large C++/COM API for a Windows
> application via JNI. I cannot see a way to implement one particular
> feature of this API, so I'm posting here to see if it is:
>
> a) impossible
> b) possible with a little cleverness
> c) trivial and I have simply missed something obvious.
>
> The API includes a function to add menu items to a Windows application.
> The COM API call in C++ looks like this:
>
> AddMenuItem("SomeMenuItem@SomeMenu","someFunctionToCall");
>
> The 'someFunctionToCall' parameter is the name of the method to be
> called in the native code. I cannot see a way to implement this on the
> Java side since the native code doesn't even know that Java is involved.
>
> The most I can do is point the native code to a single function for all
> added menu items, but then I have no way of knowing which menu item's
> action needs to be performed.
>
> I suspect that this is impossible but if anyone believes otherwise, feel
> free to comment.

How about generating the necessary C++ functions at build time, that all
just delegate to their Java counterparts? Shouldn't be too hard with Ant
and XDoclet, I reckon. Just tag the relevant methods and use a custom
doclet.
Michiel
 
Jim Sculley





PostPosted: 2004-4-7 6:04:00 Top

java-programmer >> Clever JNI solution needed Michiel Konstapel wrote:
> On Thu, 25 Mar 2004 20:01:32 -0500, Jim Sculley
> <email***@***.com> wrote:
>
>> I'm wrapping some Java around a large C++/COM API for a Windows
>> application via JNI. I cannot see a way to implement one particular
>> feature of this API, so I'm posting here to see if it is:
>>
>> a) impossible
>> b) possible with a little cleverness
>> c) trivial and I have simply missed something obvious.
>>
>> The API includes a function to add menu items to a Windows
>> application. The COM API call in C++ looks like this:
>>
>> AddMenuItem("SomeMenuItem@SomeMenu","someFunctionToCall");
>>
>> The 'someFunctionToCall' parameter is the name of the method to be
>> called in the native code. I cannot see a way to implement this on
>> the Java side since the native code doesn't even know that Java is
>> involved.
>>
>> The most I can do is point the native code to a single function for
>> all added menu items, but then I have no way of knowing which menu
>> item's action needs to be performed.
>>
>> I suspect that this is impossible but if anyone believes otherwise,
>> feel free to comment.
>
>
> How about generating the necessary C++ functions at build time, that all
> just delegate to their Java counterparts? Shouldn't be too hard with Ant
> and XDoclet, I reckon. Just tag the relevant methods and use a custom
> doclet.
> Michiel

I was able to solve this problem by doing some testing to see just what
the Windows app was doing/expecting. The bottom line is that all menu
callbacks are expected to be handled by an implementation of the COM
IDispatch interface. So, it was actually quite simple to create an
IDispatch implementation that passes calls to a Java class that actually
does the work.

I have a MenuHandler class that maintains an ActionMap whose keys are
unique integers. Each integer is the ID of an action. Any time a menu
item is added (with its associated Action) it is assinged an ID and is
stored in the ActionMap. When the native code sees a click on a menu
item, it calls the Invoke() function on the IDispatch implementation,
passing in the DISPID of the function to call. By making the DISPIDs
match the Action IDs, it is trivial to make the whole thing work without
having to do any code generation or artificially limit the number of IDs.

Thanks to all who replied.

Jim S.

--
Remove my extraneous mandibular appendages to reply via email.