Just starting out? Need help? Post your questions and find answers here.
Stefan Schnell
User
Posts: 85 Joined: Wed May 07, 2003 2:53 pm
Location: Germany - Oberirsen
Contact:
Post
by Stefan Schnell » Sat May 28, 2016 8:42 am
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
cas
Enthusiast
Posts: 597 Joined: Mon Nov 03, 2008 9:56 pm
Post
by cas » Sat May 28, 2016 1:14 pm
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
Stefan Schnell
User
Posts: 85 Joined: Wed May 07, 2003 2:53 pm
Location: Germany - Oberirsen
Contact:
Post
by Stefan Schnell » Sun May 29, 2016 5:53 am
Hello cas,
thanks for your reply, but no solution delivers the expecting result.
Cheers
Stefan
Lunasole
Addict
Posts: 1091 Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:
Post
by Lunasole » Sun May 29, 2016 6:27 am
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)
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
cas
Enthusiast
Posts: 597 Joined: Mon Nov 03, 2008 9:56 pm
Post
by cas » Sun May 29, 2016 9:56 am
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.
This calculation is wrong (same thing as in first post), try adding 3rd parameter and you will see IMA. This is correct:
fryquez
Enthusiast
Posts: 391 Joined: Mon Dec 21, 2015 8:12 pm
Post
by fryquez » Sun May 29, 2016 10:16 am
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.
cas
Enthusiast
Posts: 597 Joined: Mon Nov 03, 2008 9:56 pm
Post
by cas » Sun May 29, 2016 10:43 am
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...
Stefan Schnell
User
Posts: 85 Joined: Wed May 07, 2003 2:53 pm
Location: Germany - Oberirsen
Contact:
Post
by Stefan Schnell » Sun May 29, 2016 8:31 pm
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
cas
Enthusiast
Posts: 597 Joined: Mon Nov 03, 2008 9:56 pm
Post
by cas » Sun May 29, 2016 9:56 pm
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)