Link to home
Start Free TrialLog in
Avatar of adcode
adcode

asked on

Java, JNI, C++ and a Delphi dll

I asked this question to the Java Folks but I think that the answer will probably come from here. If you answer well here then you can get the 250 points from the java group also.

I have a dll that was originally written in Delphi. The Delphi dll is designed to interface with a (windows) program that is already running. I wrote a C++ wrapper for the Delphi dll so I could use JNI to interface between my application and the windows one.

Everything seems to work when I have a console application. When I interface with the dll from a JFrame it also works, right up until I terminate the application (using System.exit(0) or the defaultClose Operation on a JFrame). Then I get the following error messages:

First Window Title - "java.exe - Application Error"
Message - "The exception unknown software exception (0x0eedfade) occured in the application at location 0x77e6d756"

Second Window Title "Error"
Message - "Runtime Error 217 at 0F05B976"

The java code is shown below. Note that if I just comment out "frame.setVisable(true)" I no longer get the error.

package oziphoto.nat;

import javax.swing.*;

public class OZIJava{
 
 static {
   System.loadLibrary("ozijava");
 }
 

 
 public native int joziLoadWPFile(String filename);
   
 public native int joziFindOZI();
 
 public static void main(String[] args){
     OZIJava test = new OZIJava();
     if(test.joziFindOZI()==0){
         test.joziLoadWPFile("D:\\Documents and Settings\\alistair\\Desktop\\out.wpt");
     }
     JFrame frame = new JFrame();                    
     frame.setVisible(true);
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}



The c++ code is:

#include <jni.h>
#include "OZIJava.h"

HINSTANCE oziApiDll;  

ToziLoadWPfile oziLoadWPfile;
ToziFindOzi oziFindOzi;


JNIEXPORT jint JNICALL Java_oziphoto_nat_OZIJava_joziLoadWPFile
 (JNIEnv * env, jobject jobj, jstring name) {
   LoadOziApiDll();
 
   
   int return2;
   
   const char *str;

   str = env->GetStringUTFChars(name, 0);

    LPSTR FileName = (LPSTR)malloc(50);
   strcpy(FileName, str);
   return2 = oziLoadWPfile(&FileName);
   free(FileName);
   
   env->ReleaseStringUTFChars(name, str);
   

   return return2;
}

JNIEXPORT jint JNICALL Java_oziphoto_nat_OZIJava_joziFindOZI
(JNIEnv * env, jobject jobj){
    LoadOziApiDll();

    return oziFindOzi();
}
   


int LoadOziApiDll(void)
{


    oziApiDll = LoadLibrary("oziapi.dll");
    if (oziApiDll == NULL)  {return -1;}

    oziFindOzi = (ToziFindOzi)GetProcAddress(oziApiDll,"oziFindOzi");
    if (!oziFindOzi) { FreeLibrary(oziApiDll);return -2;}

    oziLoadWPfile = (ToziLoadWPfile)GetProcAddress(oziApiDll,"oziLoadWPfile");
    if (!oziLoadWPfile) { FreeLibrary(oziApiDll);return -2;}


return 0;

}

And the header is:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "windows.h"
/* Header for class OZIJava */

typedef int (CALLBACK* ToziLoadWPfile)(char **);
typedef int (CALLBACK* ToziFindOzi)(void);

#ifndef _Included_OZIJava
#define _Included_OZIJava

extern HINSTANCE oziApiDll;
extern ToziFindOzi oziFindOzi;
extern ToziLoadWPfile oziLoadWPfile;
int LoadOziApiDll(void);

#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     OZIJava
* Method:    joziLoadWPFile
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_oziphoto_nat_OZIJava_joziLoadWPFile
 (JNIEnv *, jobject, jstring);

/*
* Class:     oziphoto_nat_OZIJava
* Method:    joziFindOZI
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_oziphoto_nat_OZIJava_joziFindOZI
 (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

I think that this may have something to do with the finalization of the c++ or delphi stuff. I am not a really good c++ programmer (as you can see). If you re-write my c++ code so it is cleaner and simpler I would appriciate it greatly. I was only cutting and pasting bits out of other c++ examples.

I do not have access to the delphi dll's source.

Regards,

Alistair
Avatar of Kocil
Kocil

You can call your Delphi dll directly without using C++ wrapper.
Check this site http://home.pacifier.com/~mmead/
Avatar of adcode

ASKER

If I had the source and a compiler for Delphi I think I could do that. All I have is the Delphi dll and some documentaion about the available methods to call. Because of this I neeed some kind of native wrapper. Please correct me if I am wrong.
Yeah you are not wrong.
I didn't read that you don't have the Delphi source :).
However, you said you are not good at C++,
so maybe it is more comfortable for you to write the wrapper at Delphi :)

Anyway, I saw nothing strange with your C++ source.
All of allocations and deallocations are matched.
I suspect the problem is on the Delphi DLL or the Java code.

On Delphi, Runtime error 217 is defined as:
  Delphi Runtime Errors
    ...
    STATUS_ACCESS_VIOLATION: 216;
    STATUS_CONTROL_C_EXIT: 217;
    STATUS_PRIVILEGED_INSTRUCTION: 218;
So it might be your library is not correctly unloaded.
At the Java source, I can see the instruction of System.loadLibrary("ozijava"), but there is no matching to unload it.

Another possibility from http://www.annoyances.org/exec/forum/win98/r1041835777
re: Runtime error 217
Sunday, January 5, 2003 at 10:49 pm
Windows 98 Annoyances Discussion Forum
Posted by Everett  

Toon:  Runtime error 217 can be caused if/by;

1. Application DLLs failed registration during install.
2. an outdated version of Microsoft's MSVCRT.DLL on your system.
3. your MS DCOM is outdated.
4. the Microsoft file stdole32.tlb is gone or missing from your system.
5. the format for dates in your regional settings.
if you are using ‘Your Country' and the date format is not 'mm/dd/yy' or 'mm/dd/yyyy'; change it.

ASKER CERTIFIED SOLUTION
Avatar of heyhey_
heyhey_

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks !