José,
I've been looking at the Iup gui framework again for both "c" and PBCC 6.0.
I did translate a few declares to PowerBASIC but how does one return a char* ?
char* IupGetAttribute(Ihandle* ih, const char* name);
James
Did you try, as String
it should do it just fine.
...
Declare it AS DWORD and later assign the return value to a variable declared as ASCIIZ PTR.
DIM psz AS ASCIIZ PTR
psz = IupGetAttribute (...)
When using EXPORT AS STRING (from a DLL) that should be already translated into an ASCIIZ PTR, at least it has always worked for me with WinDev.
Using this code:
sLabel is string = StringRetrieve(API(GDImage, "ZD_GetObjectImageLabel", nID), srASCIIZAddress)
...
Thanks guys.
I was sure José's version was the only way to go but String seems to work also.
this code works fine.
Declare Sub IupMessage CDECL IMPORT $DLLNAME ALIAS "IupMessage"(ByRef stringz,ByRef stringz)
Declare Function IupVersion CDECL IMPORT $DLLNAME ALIAS "IupVersion"() As String
IupMessage("IupVersion",IupVersion())
James
String does not really work as it should
Local s As String
Local szptr As stringz ptr
s = IupVersion()
No errors but the len is zero
? s prints nothing
although the data is there.
szptr = StrPtr(s)
? @szptr -> 3.10.1
James
That's the way it should work, because a function always return a pointer, even when you export a string.
What you should do is something like this to read an exported PowerBASIC string, into a C++ char.
char strC[MAX_PATH] = { 0 };
MoveMemory(&strC[0], MyPowerBASICExportedStringFunction(), MAX_PATH)
And to ease the mixing of my multi-language DLLs i always use STDCALL never CDECL.
...
With PowerBASIC, the simplest solution is the one that I have posted. You assign the returned value to a pointer variable and get the content deferencing it.
QuoteWith PowerBASIC, the simplest solution is the one that I have posted
.
That's for sure, because everything is stored at a specific memory address.
And this is also the reason why the PowerBASIC function could just be
exported as string.
Things get a little more complex when you have to deal with either ANSI or UNICODE strings.
In that case i prefer to use MoveMemory, because for me it is the easiest way to bypass the strict C++ assignment.
...
Patrice,
I really do appreciate your insight but this topic is about PBCC 6.0 using a third party "c" dll.
My focus at present is putting together a PBCC 6.0 & RadAsm3 package for creating gui applications similar to my bc9Adp.
Again I REALLY DO appreciate ALL your input.
James
My mistake, i thought you wanted to display an exported PowerBASIC string into C.
Re-reading your first message i see that i didn't understood it well :)
This is how I think I am going to approach the return of a char*
Declare Function IupVersion_ CDECL IMPORT $DLLNAME ALIAS "IupVersion"() As Dword
Macro Function IupVersion
MacroTemp szptr
Dim szptr As StringZ Ptr
szptr = IupVersion_()
End Macro = @szptr
Then I can use it like this with the IupMessage
Local s As String
s = IupVersion
IupMessage("IupVersion",Byval STRPTR(s))
or let the compiler do the conversion by using (s).
IupMessage("IupVersion",(s))
MessageBox(0,(s),"Caption",%MB_OK)
Now is there a real need for the macrotemp?
This also appears to work fine
Macro Function IupVersion
Dim macroszptr As StringZ Ptr
macroszptr = IupVersion_()
End Macro = @macroszptr
James
Quote
Now is there a real need for the macrotemp?
Yes.
Quote
This also appears to work fine
Try to call it twice a you will get a duplicate error.
MACROTEMP forces the compiler to add suffix numbers to the variable name to avoid duplicate errors.
How about if I use a GLOBAL :o outside the macro?
James
I don't like globals, but it's your business.
I prefer to use functions than macros to avoid name conflicts.
I agree about encapsulating the C function in a powerBASIC one.
This is also very handy to ensure that the third party DLL is available, with the help of LoadLibrary.
...