JNA Cpp-DLL String Verwendung

Diskutiere JNA Cpp-DLL String Verwendung im Allgemeine Java-Themen Bereich.
Z

Zoerre

Hi zusammen,

ich versuche gerdae eine DLL mit Cpp zu erstellen und die bei mir in mein Java-Prg via JNA einzubingen.

Dazu habe ich die DLL erstellt:

Header Library.h:

Code:
#pragma once

#include <string>

extern "C" __declspec(dllexport) int testMethodInt(int paraminput);

extern "C" __declspec(dllexport) std::string * testMethodString(std::string* paraminput);
C++ Klasse Library.cpp:
Code:
#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier

#include <string>
#include "Library.h"
#include <iostream>


int testMethodInt(int inputParam) {
    int test = inputParam + 5;
    return test;
}



std::string* testMethodString(std::string* inputParam) {
    previous = previous + 1;
    std::string test = "HALLO";
   
    test = test + *inputParam;

    return &test;
}



Auf der Java-Seite habe ich ein Interface erstellt über welches ich die DLL laden will...
Code:
import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.ptr.ShortByReference;
import com.sun.jna.win32.StdCallLibrary;



public interface ICPPDLLTest   extends StdCallLibrary{
    ICPPDLLTest INSTANCE = (ICPPDLLTest) Native.load("absPath\\TestDLLCPP.dll"
            , ICPPDLLTest.class);
   
   
    public interface eventCallback extends Callback {
        public void callback(int id);
    }
   

    int  testMethodInt(int test);
   
    String  testMethodString(String test);
}

Dazu eine Testklasse:
Code:
public class CPPDLLTest {

    public static void main(String[] args) {
        ICPPDLLTest test = ICPPDLLTest.INSTANCE;
       
       
        System.out.println("testMethodInt: " + test.testMethodInt(5));
        System.out.println("testMethodInt: " + test.testMethodInt(11));
       
       
        System.out.println("testMethodString: " + test.testMethodString("asd"));
        System.out.println("testMethodString: " + test.testMethodString("asdXXX"));

    }

}

diese hat folgende Ausgabe;

testMethodInt: 10
testMethodInt: 16
Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokePointer(Native Method)
at com.sun.jna.Function.invokePointer(Function.java:497)
at com.sun.jna.Function.invokeString(Function.java:660)
at com.sun.jna.Function.invoke(Function.java:434)
at com.sun.jna.Function.invoke(Function.java:361)
at com.sun.jna.Library$Handler.invoke(Library.java:265)
at com.sun.proxy.$Proxy0.testMethodString(Unknown Source)
at CPPDLLTest.main(CPPDLLTest.java:19)





Scheinbar hat er hier Probleme mit der Übergabe des Strings, disen habe ich auch bereits versucht mittels Hilfsklasse als Pointer zu übergeben ohne Erfolg.
Code:
 public class StringByReference extends ByReference {
     public StringByReference() {
         this(0);
     }

     public StringByReference(int size) {
         super(size < 4 ? 4 : size);
         getPointer().clear(size < 4 ? 4 : size);
     }

     public StringByReference(String str) {
         super(str.length() < 4 ? 4 : str.length() + 1);
         setValue(str);
       
     }

     private void setValue(String str) {
         getPointer().setString(0, str);
     }

     public String getValue() {
         return getPointer().getString(0);
     }
}




Hat jemand eine Idee ? Übergabe als chararray oder ähnliches ?
 
MoxxiManagarm

MoxxiManagarm

Ich bin mir eher unsicher, was die cpp-Seite betrifft. Sollte es bei cpp nicht eher ein char-Array sein?
 
Z

Zoerre

So,

ich habs mal über ein Bytearray Pointer zusammengeschustert. Funktioniert! Aber ist etwas umständlich, da ich imme die Länge des Array mitgeben muss, da der Pointer dies eben nicht weiß.

Wenn jemand ein besseres Vorgehen kennt bitte melden😇


Für alle die eventuell auch mal vor dem Problem stehen hier wie ich es nun umgestzt habe:

C++ Header:
Code:
extern "C" __declspec(dllexport) std::string * testMethodString(BYTE* paraminput, int lengthParam);
C++ Klasse (oder nur Datei ? => bin ich mir nicht sicher welche ausdruck hier stimmt ist eigentlich keine Klasse):
Code:
std::string* testMethodString( BYTE* inputParam, int lengthParam) {
    previous = previous + 1;
    std::string ret = "HALLO";
  
    std::string s(reinterpret_cast<char const*>(inputParam), lengthParam);
    std::cout << "std::cout from DLL-Side: " + s << std::endl;


    ret = ret.append(s);

    std::cout << "std::cout from DLL-Side (ret var): " + ret << std::endl;

    return &ret;
}


Java-Interface
Code:
String  testMethodString(byte[] test, int length);

Java-Test Methode:
Code:
        ICPPDLLTest test = ICPPDLLTest.INSTANCE;
      
        System.out.println("testMethodInt: " + test.testMethodInt(5));
        System.out.println("testMethodInt: " + test.testMethodInt(11));
      
        String var = "aaa";
        System.out.println("testMethodString: " + test.testMethodString(var.getBytes(), var.length()));
        var = "aaabbb";
        System.out.println("testMethodString: " + test.testMethodString(var.getBytes(), var.length()));
        var = "aaabbbccc";
        System.out.println("testMethodString: " + test.testMethodString(var.getBytes(), var.length()));

Ausgabe
testMethodInt: 10
testMethodInt: 16
std::cout from DLL-Side: aaa
std::cout from DLL-Side (ret var): HALLOaaa
testMethodString:
std::cout from DLL-Side: aaabbb
std::cout from DLL-Side (ret var): HALLOaaabbb
testMethodString: HALLOaaabbb
std::cout from DLL-Side: aaabbbccc
std::cout from DLL-Side (ret var): HALLOaaabbbccc
testMethodString: HALLOaaabbbccc




Warum der erste Aufruf keinen Wert zurück lieferet ist mir auch schleierhaft....
 
Thema: 

JNA Cpp-DLL String Verwendung

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben