Verständnissfrage zu JNA

Status
Nicht offen für weitere Antworten.

Giftstachel

Bekanntes Mitglied
Moinmoin,

ich versuche grade ein interface mit hilfe von jns zu coden, jedoch ist die doku für mich irgendwie nicht verständlich.

die funktion in c++ sieht folgendermaßen aus:

Code:
Init(slot,Zeiger auf Ausgabefenster)

Code:
Schreiben(slot,Zeiger auf Datenblock, Größe des übergebenen Datenblocks )

Code:
Lesen (slot,  Zeiger auf Datenblock, Größe des übergebenen Datenblocks)

ich versuche nun die funktion in der dll aufzurufen mit:

Code:
import com.sun.jna.Structure;

public class InitIF 
{

		public static class Init extends Structure 
		{
			short 	slot;
			int 	datenBlockGröße;
			int 	timer;
		
		}
		
		void Init(Init result){}
}

oder muss ich eventuell dieses dafür nutzen?

Code:
// Equivalent JNA mappings
public interface CLibrary extends Library {
    interface FUNCTION extends Callback {
        void callback();        
    }
    int atexit(FUNCTION fn);
}
...
CLibrary lib = CLibrary.INSTANCE;
lib.atexit(new FUNCTION() {
    public void callback() {
        System.out.println("exit was called");  
    }
});

welches dann so aussehen müsste?

Code:
public interface DLL extends Library {
    interface Init extends Callback {
        void callback();        
    }
    int atexit(Init fn);
}

DLL libDll = DLL.INSTANCE;
DLL.atexit(new Init() {
    public void callback() {
        System.out.println("exit was called");  
    }
});


wie kann ich nun den slot und den Zeiger an die dll übergeben?

an sich sollte von der dll dann wenn ich sie richtig aufgerufen habe die rückantwort (slot) kommen.

nur leider steige ich dort ehrlich gesagt trotz inzwischen 10maligem durchlesen von https://jna.dev.java.net/ überhaupt nicht durch. :(
 

thE_29

Top Contributor
Ich verstehe irgendwie nicht, warum du ne Struktur anlegst, wenn es einfach immer normale Variablen erwartet?!

Vorallem, welche Methoden sind es den jetzt genau?
 

Giftstachel

Bekanntes Mitglied
Aufgabenstellung:

ich soll von einem vorgegebenen programm, und einer dll daten auslesen, und verarbeiten.

in der dll sind die oben vorgegebenen funktionen Init, Schreiben und Lesen verankert.

um das ganze zu starten muss ich es mit der funktion Init initiieren.

dann kann ich angeblich mit der funktion write weitere daten an die dll senden, und bekomme dann auch irgendwie irgendwas zurück, was ich wiederum mit Read auslesen kann...

warum ich eine struktur anlege, kann ich dir auch nicht genau sagen, da ich wie gesagt irgendwie ein sehr eingeschränktes verständniss zu dieser doku besitze, auf gut deutsch, glaub ich, bin ich einfach nur zu blöd, um die zu verstehen :/

hab mich auch schon mit nlink versucht, aber da bin ich noch viel weniger dahinter gestiegen.

hier vielleicht noch das ganze in c, und wie es dort angeblich funktionieren soll...

Code:
do
{	
	// irgendwas 
	do
{
	// Auslesen des als SLOT definierten Slots.
			nRead = BlockingRead( SLOT, pBuf, SLOT_SIZE, TIMEOUT );

} while( nRead < 0 )	// solange wie keine Daten anliegen.

// Daten (nRead Bytes) empfangen :)

// der anfang aller Daten ist der empfangene Header. 
// Um diesen auszuwerten, muss man am anfang dieses Speicherbereichs eine 
//entsprechende Datenstruktur abbilden. (‚casten’).

MessageHeader* pMsgHdr = (MessageHeader*)pBuf;

// im weiteren verlauf kann man je nach MsgId die Daten entsprechend auswerten.
switch( pMsgHdr->id )
{
	case 19: // anfragen aus der base
		HandleMyRequests( nRead, pBuf );
break;
	case 34:	// Realtime Update
		HandleMyRealtimeStocks( nRead, pBuf );
	break;
case 51: // Suchanfragen aus der Datenbank
	HandleMySearchResults( nRead, pBuf );

break;
// irgend ein anderer code

}

} while( MY_APP_IS_NOT_CRASHED && APP_IS_RUNNING );

// Zum Programmende kann Ihr Slot auf die dll geschlossen werden.
Result = Exit( SLOT, NULL );	
if( Result != SLOT )
HandleError();
 

thE_29

Top Contributor
Ich seh in dem C Source aber nie eine Init Methode oder ähnliches?!?! Funktionskopf/Parameter auch keine..

Komplett NULL Aussagend der Code da oben!

Aber wie ich sehen, brauchst du ja auch zB die ID für ein Fenster!
Wenn du zB die examples für Windows runterlädst, hast du dort die User32 Klasse und mit der geht zB das hier schon mal

Code:
    User32 user32 = (User32)Native.loadLibrary("user32",User32.class);

    System.out.println(">> " + user32.INSTANCE.FindWindow(null,"C:\\").toNative());
Hast du zB den Explorer mit C:\ offen, wird dir die HWND Handle ID angezeigt!
 

Giftstachel

Bekanntes Mitglied
ooops. dickes sorry. hab den falschen code gepostet.. *duck*


Code:
#define RET_OK    0     
#define RET_ERROR 255

#define BTR_SLOT  0     
#define MY_SLOT   11    

#define MAX_SIZE  65535 

#define LEN_SYMBOL 9
#define LEN_ISIN  17
#define LEN_RIC   17
#define LEN_NAME  41

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

#include "dll.h"
#include "blabla.h"

#pragma pack(1)
typedef struct
{
	short	queue;
	long	instance;
	long	tac;
	short	id;
} MessageHeader;

typedef struct 
{
   WORD Len;
   DWORD Curr;
   WORD    ID;  
   DWORD   WK;     
   char    Symbol[LEN_SYMBOL];
   char    Name[LEN_NAME];
} Stamm;

int SendRequest(int nSlot, char* szRequest)
{
	int rc = Init(nSlot, NULL);
	if (rc < 0)
		printf("\nFehler beim initialisieren der dll :%d", rc);
	
	MessageHeader Head;
	
	Head.tac     = 0;
	Head.queue   = MY_SLOT;
	Head.id      = 50;
	
	char szBuffer[128];
	
	memcpy(szBuffer, &Head, sizeof(MessageHeader));
	sprintf((char*)(szBuffer + sizeof(MessageHeader)), "%s", szRequest);
	
	rc = Write(nSlot, szBuffer, sizeof(MessageHeader) + strlen(szRequest));
	if (rc < 0)
		printf("\nFehler beim schreiben in die dll :%d", rc);
	
	rc = ExitTrans(nSlot, NULL);
	if (rc < 0)
		printf("\nFehler beim schließen der dll :%d", rc);
	
	return RET_OK;
};

int Read(int nSlot)
{
	int  nOffset = sizeof(MessageHeader);	
	int  nSize = MAX_SIZE;
	char szRead[MAX_SIZE];
	
	int rc = Init(nSlot, NULL);
	if (rc > 0)
	{
		do
		{
			rc = Read(nSlot, szRead, nSize);
			Sleep(1);
		}
		while (rc < 0);
		
		if (rc > sizeof(MessageHeader))
		{

			WORD wCount = *(WORD*)(szRead + nOffset);
			nOffset += sizeof(WORD);

			if (wCount)
			{
				while (wCount-- && ( nOffset < rc ) )
				{
					Stamm* pStamm = (Stamm*)(szRead + nOffset);

					printf( "\nStammId: [%d] WK: [%d] Symbol: [%s] Name: [%s]", pStamm->StammID, pStamm->WK, pStamm->Symbol, pStamm->Name );
					nOffset += sizeof( Stamm );
				}
			}
			else
				printf("\nKeine Daten empfangen !");

		}
		
		rc = Exit(nSlot, NULL);
		if (rc < 0)
			printf("\nFehler beim schließen der dll :%d", rc);
	}
	else
		printf("\nFehler beim initialisieren der dll :%d", rc);
	
	return RET_OK;
};


int main(int argc, char* argv[])
{
	char szRequest[128];
	
	WORD Flag  = 0;		
	WORD Count = 5;		
	WORD Land = 0;
	DWORD WK = 520470;
	
	sprintf( szRequest, "%d;%d;%d;%d;%s;", Flag, Land, WK, Count, "@" );
	
	int rc = SendRequest(BTR_SLOT, szRequest);
	if (rc != RET_OK)
	{
		printf("\nDaten konnten nicht gesendet werden. Fehlercode: (%d) !\n", rc);
		return RET_ERROR;
	}
	
	rc = ReadRequest(MY_SLOT);				
	if (rc != RET_OK)
	{
		printf("\nDaten konnten nicht gelesen werden. Fehlercode: (%d) !\n", rc);
		return RET_ERROR;
	}
	
	return RET_OK;

}
 

Giftstachel

Bekanntes Mitglied
ich versteh es immer noch nicht.. auch wenn ich nur zum was weiß ich wie vielten mal die doku zu jna durchgekaut, und gegoogelt habe...
 

Giftstachel

Bekanntes Mitglied
ich hoffe, ich habe funktionsköpfe richtig verstanden..

Code:
DLLIMPORT int WINAPI Write(int slot,char* pOut,int size);
DLLIMPORT int WINAPI Read(int slot,char* pIn,int size);
DLLIMPORT int WINAPI InitTrans(int slot,HWND hWnd);
DLLIMPORT int WINAPI ExitTrans(int slot,HWND hWnd);
DLLIMPORT int WINAPI BlockingRead(int slot,char* pIn,int size,int timeout);
 

thE_29

Top Contributor
Also ich hab mich mal mit einer Test DLL gespielt..
Aber irgendwie kriege ich da nie ne Funktion zum Laufen! Kp warum..

Und mit dem Funktion Mapper Bsp gehts auch nicht.. Gibts wo ein Bsp im Netz wo jemand ne eigene DLL lädt?!
 

Giftstachel

Bekanntes Mitglied
Danach bin ich auch schon seit Tagen auf der Suche.
Leider habe ich bisher nichts gefunden.

des weiteren vermute ich ja inzwischen, das ein direkter Funktionsaufruf nur möglich ist, wenn das c++ prog im hintergrund läuft.

habe mich zwischenzeitlich auch mal mit com beschäftigt. problem hierbei ist, das ich zwar ein com-bridge projekt mit hilfe von dtjcb von ibm anlegen kann, er jedoch die tlbinf32.dll als nicht registriert erkennt, obwohl ich regsvr32 tlbinf32.dll schon gemacht habe, und diese auch von windoof registriert wurde. :(
 

thE_29

Top Contributor
Najo, ob es wirklich laufen muss kann ich mir nicht vorstellen!

Meiner Meinung nach haben die DLLs ja falsche Einstiegspunkte! Meine fangen alle mit _NAME an und die kernel32.dll alle mit Namen!

Sieht man mit dem Dependincy Walker! Ich kenne das mit dem _ Namen halt nur vom JNI und dort geht das Tip Top!

Aber Bsp findet man ja auch keine.. Entweder nutzt das keiner oder jeder nutzt die vorgefertigten Klassen oder die dll muss wirklich im Hintergrund laufen..
 

Giftstachel

Bekanntes Mitglied
Giftstachel hat gesagt.:
Danach bin ich auch schon seit Tagen auf der Suche.
Leider habe ich bisher nichts gefunden.

des weiteren vermute ich ja inzwischen, das ein direkter Funktionsaufruf nur möglich ist, wenn das c++ prog im hintergrund läuft.

habe mich zwischenzeitlich auch mal mit com beschäftigt. problem hierbei ist, das ich zwar ein com-bridge projekt mit hilfe von dtjcb von ibm anlegen kann, er jedoch die tlbinf32.dll als nicht registriert erkennt, obwohl ich regsvr32 tlbinf32.dll schon gemacht habe, und diese auch von windoof registriert wurde. :(

--> hat sich erledigt, war die falsche version der tlbinf32.dll hatte die 1.0, benötigte aber mind, die 1.4

nun ergibt sich ein anderes probelm, welches lautet folgendermaßen...: MSDEV wurde nicht gefunden. liegt am servicepack für c++ visual studio 2005. und jetzt kommts: sp5 oder 6 lassen sich nicht vollständig installieren *ggg* ich schmeiß mich weg. mal gucken woran das nun wieder liegt. lösung poste ich dann auch noch.

BeitragVerfasst am: 20. 12. 2007, 9:42 Titel:
Najo, ob es wirklich laufen muss kann ich mir nicht vorstellen!

Meiner Meinung nach haben die DLLs ja falsche Einstiegspunkte! Meine fangen alle mit _NAME an und die kernel32.dll alle mit Namen!

Sieht man mit dem Dependincy Walker! Ich kenne das mit dem _ Namen halt nur vom JNI und dort geht das Tip Top!

Aber Bsp findet man ja auch keine.. Entweder nutzt das keiner oder jeder nutzt die vorgefertigten Klassen oder die dll muss wirklich im Hintergrund laufen..
jup, danke, ich werd das mal gegenprüfen, ob das mit den einstiegspunkten der fall ist.

der dependency walker ist ja klasse, vielen dank, der kann einem echt weiterhelfen :)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben