2009-07-31 12 views
3

Ich rufe eine DLL mit der Übergabe eines Callback-Functio-Objekts an sie auf. Eine der Funktionen ist der einfache Druck. Ich habe dann, eine Schleife von 100 Iterationen, nur den Index und ein paar Drucke nach der Schleife drucken.JNA - Zugriffsverletzung, JVM-Terminale


Hier ist der C-Code

extern "C" int Start(void* callback(CString)) 
{ 
    for(int j=0; j<100; j++) 
    callback(AConvertToString(j)); 

    callback("in Start called from Java"); 
    callback("another line"); 
} 

Hier den Java-Code

public interface MyDll extends Library{ 
    MyDll INSTANCE = (MyDll) Native.loadLibrary("MyDll",MyDll.class); 
    public interface MyCallback extends StdCallCallback { 
      public boolean callback(String msg); 
    } 
    public int Start(MyCallback callback); 
    } 

//in main: 
... 
    MyDll myDll = (MyDll)MyDll.INSTANCE; 
    myDll.Start(new MyDll.MyCallback() { 
     public boolean callback(String msg) { 
     System.out.println(msg); 
      return true;   
     } 
}); 

Der Ausgang ist Zahlen 0..41 (JA 41 !!! nicht 99) und dann "in Start aus Java" gefolgt von einem schrecklichen Absturz:

# 
# An unexpected error has been detected by Java Runtime Environment: 
# 
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7c809823, pid=468, tid=2636 
# 
# Java VM: Java HotSpot(TM) Client VM (10.0-b23 mixed mode, sharing windows-x86) 
# Problematic frame: 
# C [kernel32.dll+0x9823] 

Ich habe viel gelesen (auch hier), aber ich kann das Problem nicht finden. Ich benutze JRE von Java6. Ich habe 1,5 GB Arbeitsspeicher auf meinem Rechner. Die DLL wird von keinem anderen Prozess verwendet (keine Nebenläufigkeitsprobleme).

Danke, Azriel

+0

Vielleicht ist die Aufrufkonvention Ihrer DLL nicht StdCall? – akarnokd

+0

Anstatt mit beantwortet zu beginnen, sollten Sie die Antwort "akzeptieren" (klicken Sie auf das Häkchen). –

Antwort

4

Versuchen Sie, Ihre MyCallback als com.sun.jna.Callback stattdessen als com.sun.jna.win32.StdCallLibrary.StdCallCallback zu schreiben:

public interface MyDll extends Library{ 
    MyDll INSTANCE = (MyDll) Native.loadLibrary("MyDll",MyDll.class); 
    public interface MyCallback extends Callback { 
      public boolean callback(String msg); 
    } 
    public int Start(MyCallback callback); 
    } 

Grüße, Emmanuel Girard

+0

Danke, das hat den Trick gemacht. So eine kleine Sache ... – aabramovich

2

In meinem Fall Entwicklung einer Telekom-Anwendung, die eine Win32-DLL verwendet, war es der umgekehrte Fall.

Mit com.sun.jna.Library und com.sun.jna.Callback stürzte die VM immer ab, wenn sie vom Rückruf zurückkam.

Nach dem Wechsel zu com.sun.jna.win32.StdCallLibrary und com.sun.jna.win32.StdCallLibrary.StdCallCallback wurde das Problem gelöst.