Page 1 of 1

Convert C-DLL to PureBasic-DLL

Posted: Sat May 28, 2016 8:42 am
by Stefan Schnell
Hello community,

I have this C-DLL:

Code: Select all

//-Begin----------------------------------------------------------------

  //-Includes-----------------------------------------------------------
    #include <windows.h>

  //-Structures---------------------------------------------------------
    struct TestStruct3 {
      wchar_t *str;
    };

  //-strucTest22--------------------------------------------------------
    __declspec(dllexport) void strucTest22(struct TestStruct3 **astruc,
      int n) {
      for (int i = 0; i < n; i++) { 
        wchar_t *str = astruc[i]->str;
        OutputDebugStringW(str);
      }
    }

//-End------------------------------------------------------------------
and I want to convert it to a PureBasic-DLL, e.g. like this:

Code: Select all

; Begin-----------------------------------------------------------------

  ; Structures----------------------------------------------------------
    Structure TestStruct3
      *x
    EndStructure

  ; strucTest22---------------------------------------------------------
    ProcedureDLL strucTest22(*astruc.TestStruct3, cnt.i)
      Protected i.i
      For i = 0 To cnt - 1
        *astruc = *astruc + i * 4
        OutputDebugString_(PeekS(*astruc\x))
      Next
    EndProcedure

; End-------------------------------------------------------------------
but it doesn't work. What is my error?
I have already tested several variants but without success.

Thanks for tips and hints.

Cheers
Stefan

Re: Convert C-DLL to PureBasic-DLL

Posted: Sat May 28, 2016 1:14 pm
by cas
Problem is definitely in this loop:

Code: Select all

For i = 0 To cnt - 1
  *astruc = *astruc + i * 4 ;<-- this calculation is wrong
  OutputDebugString_(PeekS(*astruc\x))
Next
Try with this and see if you get expected result:

Code: Select all

For i = 0 To cnt - 1
  OutputDebugString_(PeekS(*astruc\x))
  *astruc+SizeOf(Integer)
Next
And maybe PeekS it not needed?

Code: Select all

For i = 0 To cnt - 1
  OutputDebugString_(*astruc\x)
  *astruc+SizeOf(Integer)
Next

Re: Convert C-DLL to PureBasic-DLL

Posted: Sun May 29, 2016 5:53 am
by Stefan Schnell
Hello cas,

thanks for your reply, but no solution delivers the expecting result.

Cheers
Stefan

Re: Convert C-DLL to PureBasic-DLL

Posted: Sun May 29, 2016 6:27 am
by Lunasole
Hi. It works fine when used with PB code (as following example).
Or you can check commented lines also:

Code: Select all

EnableExplicit

; Structures----------------------------------------------------------
Structure TestStruct3
	*x
EndStructure


; strucTest22---------------------------------------------------------
;ProcedureCDLL strucTest22(*astruc.TestStruct3, cnt.i) ; try this 
ProcedureDLL strucTest22(*astruc.TestStruct3, cnt.i)
	Protected i.i
	For i = 0 To cnt - 1
		*astruc + i * SizeOf(Integer)
		Debug (PeekS(*astruc\x))
		;Protected s$ = (PeekS(*astruc\x)) : OutputDebugString_(@s$) ; or this
	Next
EndProcedure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Dim A.TestStruct3 (1)
a(0)\x = @"asdf"
a(1)\x = @"zxcv"

strucTest22(@A(0), 2)

Re: Convert C-DLL to PureBasic-DLL

Posted: Sun May 29, 2016 9:56 am
by cas
Stefan Schnell wrote:Hello cas,

thanks for your reply, but no solution delivers the expecting result.

Cheers
Stefan
What output do you get? What is expected output?
Give us some small example with some test data for this function and we will figure it out.
Lunasole wrote:

Code: Select all

*astruc + i * SizeOf(Integer)
This calculation is wrong (same thing as in first post), try adding 3rd parameter and you will see IMA. This is correct:

Code: Select all

*astruc + SizeOf(Integer)

Re: Convert C-DLL to PureBasic-DLL

Posted: Sun May 29, 2016 10:16 am
by fryquez
Try this

Code: Select all

Structure IntegerArray
  i.i[0]
EndStructure

ProcedureDLL strucTest22(*astruc.IntegerArray, cnt.i)
   Protected i.i
   For i = 0 To cnt - 1
      Debug PeekS(*astruc\i[i], -1, #PB_Unicode)
      OutputDebugString_(*astruc\i[i])
   Next
EndProcedure
BTW: I want to use OutputDebugString_() compile as Unicode.

Re: Convert C-DLL to PureBasic-DLL

Posted: Sun May 29, 2016 10:43 am
by cas
Your code does exactly the same thing as the ones above, only without wrong calculations because you defined structure element as array so PureBasic compiler does all the calculations under the hood. This is the best way to do it.

We need to wait for some more info... Maybe structure needs to be aligned to some boundary...

Re: Convert C-DLL to PureBasic-DLL

Posted: Sun May 29, 2016 8:31 pm
by Stefan Schnell
Hello cas, fryguez and Lunasole,

thanks for your reply.

As far as I can find out is **astruc in C a pointer of pointer to char. If I add PeekI(*astruc) to dereference the pointer all works as expected. It seems that C automatically dereference a pointer to a pointer.

The suggestion of cas with SizeOf(Integer) is very good for x86 and x64 programming - thanks for that.

Cheers
Stefan

Re: Convert C-DLL to PureBasic-DLL

Posted: Sun May 29, 2016 9:56 pm
by cas
Glad to hear you figured it out.
This would be the best way (works in both x86 and x64) to traverse that array:

Code: Select all

EnableExplicit

Structure TestStruct3
  *x.Integer[0]
EndStructure

ProcedureDLL strucTest22(*astruc.TestStruct3, cnt.i)
  Protected i.i
  For i = 0 To cnt - 1
    Debug PeekS(*astruc\x[i]\i)
    ;OutputDebugString_(*astruc\x[i]\i)
  Next
EndProcedure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Define *ptr1=@"string1"
Define *ptr2=@"string2"
Define *ptr3=@"string3"

Dim A(2)
a(0) = @*ptr1
a(1) = @*ptr2
a(2) = @*ptr3

strucTest22(@A(0), 3)