Smart questions
Smart answers
Smart people
Join Tek-Tips Forums

Member Login

Remember Me
Forgot Password?
Join Us!

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.
Jobs from Indeed

Link To This Forum!

Partner Button
Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

KempCGDR (Programmer) (OP)
26 Mar 05 20:13
Hi, I have this piece of code in the onJoin event of an Indy IRC Client:


procedure TfrmMain.ircJoin(Sender: TObject; AUser: TIdIRCUser; AChannel: TIdIRCChannel);
   TonJoin = function(AUser: TIdIRCUser; AChannel: TIdIRCChannel):String;
   displayEvent(AUser.Nick, 'has joined the chat');

   Temp := PChar(ExePath + dll);
   LibraryID := LoadLibrary(Temp);
   If LibraryID <> null then
      proc := GetProcAddress(LibraryID, 'onJoin');
      if proc <> nil then
         command := TonJoin(proc)(AUser, AChannel);
         displayChat(irc.Nick, command);
         irc.Say(currChannel, command);

It basically allows me to do basic scripting via a DLL. It all works fine except that after this code has ran once, the client appears to ignore any new incoming messages and disconnecting results in a socket error. After a lot of testing and swearing I managed to narrow it down to the FreeLibrary call, if I comment that out then it works perfectly and nothing dies. Is there anything blatently wrong with that code? I can't see it for the life of me.
Helpful Member!  whosrdaddy (Vendor)
27 Mar 05 4:11
are you using threads in the DLL ?

 What You See Is What You Get

KempCGDR (Programmer) (OP)
27 Mar 05 5:17
the dll function is the most simple one I could write for testing purposes:


function onJoin(AUser: TIdIRCUser; AChannel: TIdIRCChannel):String;
   onJoin := 'Hi ' + AUser.Nick;

I don't see that there could be anything bad going on there.
whosrdaddy (Vendor)
27 Mar 05 16:04
very bad things!!!, you are passing strings from DLL to app, this requires that you use the Sharemem Unit from borland. that's why you get the AV on freeing the DLL.
you got 2 options here :

1) use ShareMem (then you must include borlands borlndmm.dll) or a third party memory manager (I use FastShareMem (google it), no DLL required, just use the unit in both the app and the DLL)

2) avoid using strings between app and DLL and use Pchar.

and you got a third option but I don't recommend this one :

use shortstrings, these don't require a sharemem unit.

hope this helps,


 What You See Is What You Get

KempCGDR (Programmer) (OP)
27 Mar 05 17:30
*slaps forehead*

Ok, I'm an idiot. I knew about that as well and I've done this before the right way. How could I forget something so basic? Especially when there's a big warning in the comment block that it gives you.

As a sidenote, it also failed all the time when I was using a TStringList, I assume that was a related reason. Are there any objects like a TStringList that store PChars, or am I going to have to make one myself? I'll move over to PChars for now though.

And one last thing, lol. Say you have this:


function foo:WhateverObject
   bar : WhateverObject;
   bar := WhateverObject.Create;
   {various operations on bar}
   foo := bar;

Is bar freed automatically when the function finishes executing or will this create a memory leak? Obviously if you free bar yourself at the end then foo now points to nothing (well, nothing that's valid) and you get nothing back from the function.
whosrdaddy (Vendor)
28 Mar 05 3:45
that is totally up to you. if you free foo in the function where you called it, everything's ok, don't freeing foo will indeed create memory leaks. Offcourse there are some objects that can do the dirty work for you :


// dll

function foo:WhateverObject
   bar : WhateverObject;
   bar := WhateverObject.Create;
   {various operations on bar}
   Result := bar;
    // if we have an exception foo will be nil


uses contnrs;
var allmyobjects : TObjectList;
constructor TApp.init;
 // create a Tobjectlist that owns the objects
 // this means that the object will be freed upon deletion from the list

destructor TApp.cleanup;
 allmyobjects.Clear; // this will free all objects in the list
 // this is not really needed since clear is called upon TObjeclist.Destroy
 // but is handy to know at what point your objects are freed

procedure TApp.callingfoo;

var fooObject : TFooObject;
 if foo <> nil then
  alllmyObjects.add(fooObject); // add to list for auto destroy
  //exception handling



 What You See Is What You Get

KempCGDR (Programmer) (OP)
28 Mar 05 6:08
Yeah, it occured to me last night (I do all my best thinking when I'm meant to be going sleep) that if you don't free bar then the object is still hanging around in memory, but the return from the function gives you a new pointer to that object that you can use to free it (as you've done in the example above).

Thanks a lot for all the help

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Back To Forum

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close