Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DLL Talk / Help IanM ! - Purebasic to DBPro - globstruct and returning strings

Author
Message
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 9th Mar 2014 22:11 Edited at: 10th Mar 2014 09:19
Hi IanM, (and / or anyone else who can help clarify)

Have re-read a number of often contradictory and confusing threads on this topic.

When I am creating a DBPro plugin command in PureBASIC with a ProcedureCDLL.l, I know most of the stuff around this.

I just want to check and double check the form of the ProcedureCDLL.l that is returning a string... so apologies in advance for these questions - it may be it would be simplest if you could just post the right way to do it all in one set of purebasic code...

1. Does the ProcedureReturn variable have to have been declared as a global variable outside the Procedure to start with? What about the temporary or temp.l within

2. Assuming say the ProcedureCDLL.l starts with "ProcedureCDLL.l UsefulFunction(OldString.l,Parameter1.l,Parameter2.l)", is it correct to follow with:-

If OldString <> 0
CallCFunctionFast( *GlobPtr\CreateDeleteString, OldString , 0 )
EndIf

or with (note the ommission of the '\'):-

If OldString <> 0
CallCFunctionFast( *GlobPtrCreateDeleteString, OldString , 0 )
EndIf

3. If you're ending with:-
CallCFunctionFast(*GlobPtr\CreateDeleteString, @temp.l , Len( result ) + 1 )
PokeS( temp , result )
ProcedureReturn temp
EndProcedure

Is that correct? Should you omit the '\'? would you be declaring the temp variable and the result variable outside the Procedures as global??

4. Could you give me the latest and greatest version of all the globstruct code incl the constructor and destructor etc?

5. Do you need to create separate procedures for things like CreateDeleteString or is it enough that they are simply within the GlobStruct?

6. What is wrong with the attached? (if anything) (I've changed IsFunction to GetFunction which I believe is the new Purebasic equivalent...)
+ Code Snippet

7. Why this:-

If OldString <> 0
CallCFunctionFast( *GlobPtr\CreateDeleteString, OldString , 0 )
EndIf

and not simply:-

If *GlobPtr = 0 : InitialiseCorePtr() : EndIf

8. Why this:-

CallCFunctionFast(*GlobPtrCreateDeleteString, @temp.l, Len(result$)+1 ) ; CreateString
PokeS(temp, result$)
ProcedureReturn temp

(also, is it meant to be
CallCFunctionFast(*GlobPtr\CreateDeleteString, @temp.l, Len(result$)+1 ie. with the '\'?)

and not simply this?:-

ProcedureReturn @result$

[edit]

9. The original TPC tutorial posted with the TGC magazine simply gave this code:-

(and in this code it almost looks like Test is both an integer and then a string within the procedure and the Test.l rather looks like OldString.l..... boh!?)

ProcedureCDLL.l NumberToText( Test.l, Number.l )
If *GlobPtr = 0 : InitialiseCorePtr() : EndIf
test.s = Str( Number )
ProcedureReturn @Test
EndProcedure

[edit]

10. Is there anywhere (at the start of every ProcedureCDLL where you're returning a string or every ProcedureCDLL full stop?) you must/could/should place the following code other than in the AConstructor00YAXXZ() Procedure?:-

<< If *GlobPtr = 0 : InitialiseCorePtr() : EndIf >>

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 10th Mar 2014 09:06
@ IanM and all,

And here is the original TGC word document (attached) on how to do these commands - see section 4.3... it seems to contradict some of what I thought was correct...

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...

Attachments

Login to view attachments
Freddix
DBPro Developer
14
Years of Service
User Offline
Joined: 19th Sep 2002
Location: France
Posted: 10th Mar 2014 11:04
Hi Duffer,

Heh! I was surprised to receive an e-mail concerning DBPro ... It makes now year I didn't really use it ...

I will try to answer you while checking my old backup of these informations ...

1. The variable used for the "ProcedureReturn" needs to be LOCAL.
Declared inside the function itself, that will return the data.

2. DarkBASIC Professional does not automatically destroy/release memory used by strings so, when you create a functino that'll return a string, you'll have to delete the previous one if existing.
That's why you have OldString data received as 1st argument (not visible on the function the user will use under DarkBASIC Professional.
GlobPtr is a structure that contain pointer to some DarkBASIC PRofessional internal function like CreateDeleteString.
This function is special because it can be used both to :
- Release memory from a previous used string
- Allocate memory for a new string.

3. When you create a new string, you must allocate the string length +1 to be sure it will be finished by a 0.
the "temp" variable is like all "ProcedureReturn" variable ... LOCAL.
the "\" is important because it ensure that it will use the pointer "CreateDeleteString" available inside the "GlobPtr" structure.

4. I have no newer version.

5. CreateDeleteString is "build-in" DarkBASIC Professional core so, you don't have to create one.

6. Effectively, I've checked the doc from the latest PureBASIC build and isFunction is no more in the doc and getFunction appear. Reading it's documentation. If the only changes were isFunction->getFunction ... I suppose, it should work.
I will try this when I'll have some free time for ~.

7. These 2 quotes are differents stuffs. You must not replace one by the other.

8. All strings returned by a DarkBASIC Professional function must be created with "CreateDeleteString".

9. Original TPC tutorial is obsolete. Use the new explanation.

Regards,
Freddix.
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 10th Mar 2014 14:13
@ Freddix,

Great to hear from you and many thanks for coming back to me in on this.

So with functions returning a string that \ should be in CallCFunctionFast(*GlobPtr\CreateDeleteString, @temp.l, Len(result$)) towards the end of the ProcedureCDLL.l and also (addressing OldString.l) the \ should be in CallCFunctionFast( *GlobPtr\CreateDeleteString, OldString , 0 ) as well?

Do you ever put the " If *GlobPtr = 0 : InitialiseCorePtr() : EndIf " within a ProcedureCDLL? (when returning a string or otherwise)?

Again, many thanks for your help on this...

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 11th Mar 2014 09:07 Edited at: 11th Mar 2014 09:18
@ Freddix, IanM,

It would seem that with the latest version of PureBasic I am using, the crashes are solely related to functions returning strings. Usually, not the first time a function is called then but later iterations.

Which makes me wonder whether it's to do with CreateDeleteString?

Or some memory leak?

[edit]

an interesting thread on PB website:-

http://www.purebasic.fr/english/viewtopic.php?p=298578

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Freddix
DBPro Developer
14
Years of Service
User Offline
Joined: 19th Sep 2002
Location: France
Posted: 11th Mar 2014 10:00
Duffer :
You have the same "conclusion" than me concerning the CreateDeleteString function...
I came to this conclusion many years ago

But the CreateDeleteString is a simple function. Nothing inside may explain why it crashes with texts...
It's the most annoying issue I had concerning PureBASIC & TPC 4 DarkBASIC Professional.
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 11th Mar 2014 20:21 Edited at: 11th Mar 2014 20:22
@ Freddix, IanM,

Darn it! I am going to do some 'dumb' things now to test some theories.

1. I am going to make the temp and outputstring (result.s) variables global within Purebasic.

1a. and test.

2. I am going to shove If *GlobPtr = 0 : InitialiseCorePtr() : EndIf into the start of each ProcedureCDLL, at least where returning strings

3. Test with those amendments.

4. I am going to rid myself of CallCFunctionFast(*GlobPtrCreateDeleteString, @temp.l, Len(result$)+1 ) ; CreateString
PokeS(temp, result$)
ProcedureReturn temp
and change to
ProcedureReturn @result (as in result.s)
EndProcedure

5. Test again.

6. I am going to abandon
If OldString <> 0
CallCFunctionFast( *GlobPtr\CreateDeleteString, OldString , 0 )
EndIf
and just stick with If *GlobPtr = 0 : InitialiseCorePtr() : EndIf

7. Test again.

8. I am going to review:-

ProcedureCDLL.l AGetDependencyID00YAPBDH0Z(ID.l)
ProcedureReturn @Dependency; Return string pointer (I have previously defined Dependency as a global string in PB...)
EndProcedure

and

ProcedureCDLL.l AGetNumDependencies00YAHXZ()
ProcedureReturn 0
EndProcedure

Do I need to do something different with either of these Procedures given I have no additional DLLs to worry over? (not using PurePlugin for the purpose of this experiment)

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Freddix
DBPro Developer
14
Years of Service
User Offline
Joined: 19th Sep 2002
Location: France
Posted: 11th Mar 2014 23:16
1. Dangerous choice. see 4. to understand.

2. Useless, it's checked on setup.

3. ...

4. Dangerous because your global data stated at 1. will be deleted from memory on the next DarkBASIC Professional function that will use string .. Default DarkBASIC Professional functions/commands use CreateDeleteString and delete previous one ... so your will be deleted ... It will lead to *possible* crash in your PureBASIC DLL.

5. ...

6. It's a nonsense

7. ...

8. Dependencies are here to tell DarkBASIC Professional (at compilation time) which plugin DLL your DLL need and be sure that DarkBASIC Professional compiler will include them in the final .exe file ... Without these ... if you use other plugin/DLL from within your own plugin/DLL ... it will crash.

I have the feelin' that you're playing the "apprentice sorcerer" without learning correctly the use of each word in a spell casting ...

Regards,
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 11th Mar 2014 23:24
@ Freddix,

Thanks for the response. Your feeling is quite correct and, candidly, if you couldn't solve the string return problem with Windows Vista and Windows 7, I'm not going to be able to either...

But I'm desparate. Cue the proverbial mops out of control in the overwashed castle...

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Freddix
DBPro Developer
14
Years of Service
User Offline
Joined: 19th Sep 2002
Location: France
Posted: 12th Mar 2014 09:06
The problem is that this string issue is not a "direct" bug... Sometimes you need to call the same function several times before it crash ...
IKt's a really strange bug behaviour...
IanM
Moderator
14
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 14th Mar 2014 17:23
I don't know PureBasic beyond very simple things, but I do know the DBPro API quite well

You have this line that you use to delete the old string:
CallCFunctionFast( *GlobPtr\CreateDeleteString, OldString , 0 )

That looks wrong to me, as you are passing 'OldString' into the function, and not a pointer to OldString, which is what the function needs. I think that you need to put an @ in front of OldString.

Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 15th Mar 2014 14:40
@ IanM,

I think I see what you mean - the Oldstring element of CallCFunctionFast should be a pointer to Oldstring rather than the straight integer for the CreateDeleteString to work properly?

Will give it a whirl.

Many thanks for the suggestion - fingers crossed.

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 15th Mar 2014 15:53 Edited at: 15th Mar 2014 15:53
An interesting post from Freddix at the end of this link:-

http://forum.thegamecreators.com/?m=forum_view&t=102269&b=18

where he says:-
+ Code Snippet

So I am thinking too, it should be a pointer to the Oldstring rather than the Oldstring which is an integer?

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 15th Mar 2014 16:43
I've sorted it. I suspect it was your suggestion IanM.

I also shoved the If *GlobPtr = 0 : InitialiseCorePtr() : EndIf
in to all the procedures returning strings, at the start.

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
Freddix
DBPro Developer
14
Years of Service
User Offline
Joined: 19th Sep 2002
Location: France
Posted: 15th Mar 2014 22:59
@Duffer :

Put :
If *GlobPtr = 0 : InitialiseCorePtr() : EndIf

at the start of all your procedures returning string is useless.
It's better to add it in your "constructor" function :

ProcedureCDLL AConstructor00YAXXZ()
If *GlobPtr = 0 : InitialiseCorePtr() : EndIf
REM add your initialisation stuffs here.
EndProcedure

and then use PPFixer to change the function name AConstructor00YAXXZ to ?Constructor@@YAXXZ
With that your application developed under DarkBASIC Professional will call your Constructor function at startup. And then the CorePtr data will be retrieved (including globstruct)

Regards,
Duffer
14
Years of Service
User Offline
Joined: 9th Feb 2003
Location: chair
Posted: 16th Mar 2014 00:56
Thanks Freddix - all sorted now and works without problems...

a long time dabbler with DBC and DBPro with no actual talent but lots of enthusiasm...
IanM
Moderator
14
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base

Login to post a reply

Server time is: 2017-06-23 20:07:51
Your offset time is: 2017-06-23 20:07:51