PureBasic Forum
https://www.purebasic.fr/english/

problem calling a PB-DLL from Java
https://www.purebasic.fr/english/viewtopic.php?f=13&t=8612
Page 1 of 1

Author:  Froggerprogger [ Thu Dec 04, 2003 12:14 pm ]
Post subject: 

:?: + :idea: => :P :P :P

Yeah, I got it!
It's just as easy as... don't know

Here's the 'trick':
All you have to do is to rename your PB-Procedures.
If your Java-program calls the function 'testfunction', then your PB-procedure has to have the name 'Java_ClassNameOfCallingClass_testfunction'
That's all.
It's not soo convenient, because you have to rename your PB's procedures always if they should be called from another Java-program's class, but anyway, it works.
I tried it with byte (byte), word (short), long (int) and float (float).
I think a workaround for doubles would work, too.
But I wasn't able to send/receive a String, not even converted to a byte[]-array in Java. hmmm. It seems, that there's really a big difference in their handling, or it's not possible to access the other program's memory or something like that - I will try a little bit more.

But first, here's an example:

The PB-DLL:

Code:
ProcedureDLL.b Java_dllCallClass_testfunctionB(a.l, b.l, c.b, d.b)
  MessageRequester("",Str(a)+"   "+Str(b)+"   "+Str(c)+"   "+Str(d),0)
  ProcedureReturn c + d
EndProcedure

ProcedureDLL.w Java_dllCallClass_testfunctionW(a.l, b.l, c.w, d.w)
  MessageRequester("",Str(a)+"   "+Str(b)+"   "+Str(c)+"   "+Str(d),0)
  ProcedureReturn c + d
EndProcedure

ProcedureDLL.l Java_dllCallClass_testfunctionL(a.l, b.l, c.l, d.l)
  MessageRequester("",Str(a)+"   "+Str(b)+"   "+Str(c)+"   "+Str(d),0)
  ProcedureReturn c + d
EndProcedure

ProcedureDLL.f Java_dllCallClass_testfunctionF(a.l, b.l, c.f, d.f)
  MessageRequester("",Str(a)+"   "+Str(b)+"   "+StrF(c)+"   "+StrF(d),0)
  ProcedureReturn c + d
EndProcedure


And the Java-Code:

Code:
class dllCallClass
{
   public static native byte testfunctionB (byte c, byte d);
   
   public static native short testfunctionW (short c, short d);
   
   public static native int testfunctionL (int c, int d);
   
   public static native float testfunctionF (float c, float d);
   
   static
     {
        System.loadLibrary("testdll");
     }
}



class starttestdll
{
   public static void main(String [] parm)
    {
      dllCallClass t = new dllCallClass();
      
      System.out.println(t.testfunctionB((byte) 12,(byte) -23));

      System.out.println(t.testfunctionW((short)1234,(short)-2345));

      System.out.println(t.testfunctionL(23456,-34567));
      
      System.out.println(t.testfunctionF((float) 2.345,(float) -3.456));
      
      }
}


Just compile the DLL and copy it to the directory of the Java-file. :P

OK, now I will have a deeper look at the other types (strings, pointer, structures, arrays, lists), there is written something about it somewhere in the Net...

edit: now it's 12:17 - hmmm - i forgot to sleep last night !!! not 1 minute !!! It was just getting dark and then bright again...

Author:  Froggerprogger [ Thu Dec 04, 2003 2:27 pm ]
Post subject: 

Hmmmm. I tried now to use strings, but all I reached is a workaround-hack.
I read the C-Header-files coming along with the SDK and these documents:
http://java.sun.com/docs/books/tutorial ... tring.html
It seems that using Strings/Arrays/etc. is really a big problem that could only be solved using Instances, or something like this, because Strings and the other stuff are objects including some methods and pointer to pointer to data, etc. I have really NO knowledge about how to implement it.
All I reached during 'controlled peeking around' was to send Strings from Java to PB. Java sends the DLL a pointer, and when you look at
Code:
PeekL(PeekL(PeekL(*str)+8)+8)

you'll find the information on the string-length followed by a 16-Bit-String.
So you can read the String with:
Code:
For i=0 To strLen - 1
    str$ + Chr(PeekL(PeekL(PeekL(*str)+8)+12+2*i))
  Next

This works fine for now, but will not work with other Stringformats and it is not the fine way. And, it's not possible for me to create a new String-object in such a manner to send back to Java.
Hmmm. Does anybody perhaps have an idea how to implement the object-types Array, String, etc. :?:

edit:
Here's a snippet how to get the String:
Code:
ProcedureDLL.s GetJavaString(*str.l)
  Protected str$.s
  Protected strLen.l
 
  strLen = PeekL(PeekL(PeekL(*str)+8)+8)
 
  For i=0 To strLen - 1
    str$ + Chr(PeekL(PeekL(PeekL(*str)+8)+12+2*i))
  Next

  ProcedureReturn str$
EndProcedure

ProcedureDLL.l Java_dllCallClass_testfunctionS(a.l, b.l, c.l, d.l)
  str1$ = GetJavaString(c)
  str2$ = GetJavaString(d)
 
  MessageRequester("","length: "+Str(Len(str1$))+Chr(13)+Chr(10)+"text:  "+"   "+str1$,0)
  MessageRequester("","length: "+Str(Len(str2$))+Chr(13)+Chr(10)+"text:  "+"   "+str2$,0)
   
  ProcedureReturn 1
EndProcedure


Just implement with e.g. testfunctionS(String c, String d);

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/