Constructor in dll

General FreeBASIC programming questions.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Constructor in dll

Post by deltarho[1859] »

I cannot remember if I have asked this before.

Anyway, I have written a dll in FreeBASIC to be used in PowerBASIC.

Here is a Destructor that I am using:

Code: Select all

Sub on_exit( ) Destructor
  CloseThreadpoolWork(Work1)
  CloseThreadpoolWork(Work1plus)
  CloseThreadpool(Pool)
End Sub
I know that this is working because I tested it by inserting

Code: Select all

Print "Cleaned"
Sleep
just before 'End Sub'

However, is it possible to employ a Constructor in a dll? I have a feeling that it cannot be done and what I have tried don't work.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Constructor in dll

Post by fxm »

The dll module constructors (destructors) are called during DLL load (unload).

Example:
- dll test.bas:

Code: Select all

Sub c () Constructor
  Print "Constructor"
End Sub

Sub d () Destructor
  Print "Destructor"
End Sub

Sub t () Export
  Print "dll"
End Sub
- module.bas:

Code: Select all

#inclib "test"

Declare Sub t ()

t()
- Output:

Code: Select all

Constructor
dll
Destructor
Also works when loading shared libraries dynamically.
Last edited by fxm on May 03, 2019 19:55, edited 1 time in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Constructor in dll

Post by dodicat »

Just exports the methods(including constructors/destructors)
The dll code

Code: Select all

'tester.bas
'compile -dll

type udt
    as zstring * 20 y
    as integer n
    declare constructor
    declare destructor
    declare sub show
end type

constructor udt export
y="The year is: "
n=2019
end constructor

destructor udt export
print "Nothing to destroy"
sleep 1000
end destructor

sub udt.show export
    print y;n
end sub
  
And the dll caller

Code: Select all


#inclib "tester"
type udt
    as zstring * 20 y
    as integer n
    declare constructor
    declare destructor
    declare sub show
end type


dim as udt x
 x.show
 sleep  
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Constructor in dll

Post by deltarho[1859] »

Thanks fxm.

I have tried:

Code: Select all

Sub on_entry() Constructor
  Print "I'm open for business"
  InitializeCryptoBuffers
End Sub
InitializeCryptoBuffers used to be an exported Sub and is now a Private Sub.

On executing the PowerBASIC code I am getting "I'm open for business" but the console just goes quiet with the flashing cursor. Task Manager is showing no activity and when I click on the console close button it takes a while to close.

Obviously, there is something inside InitializeCryptoBuffers which is problematic. With InitializeCryptoBuffers as an exported sub and executed at the beginning of the PB code all is well.

Added: Note that the dll caller is a PowerBASIC application.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Constructor in dll

Post by srvaldez »

perhaps you need to look into dllmain viewtopic.php?p=136223#p136223
suggest reading the entire thread, it's educational
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Constructor in dll

Post by dodicat »

Using sub something constructor fires it up immediately, only direct instructions inside it are available (seems)
If another sub is called from the constructor sub, then that other sub won't yet have actually been created, it needs to wait for the constructor sub to have run it's course.

Example
call init from constructor fails on running the .dll

Code: Select all

'tester.bas
'compile -dll

type udt
    as zstring * 20 y
    as integer n
    declare constructor
    declare destructor
    declare sub show
end type



constructor udt export
y="The year is: "
n=2019
end constructor

destructor udt export
print "Nothing to destroy"
sleep 1000
end destructor

sub udt.show export
    print y;n
end sub


sub init
    screen 8
    end sub

sub dothis constructor 
    init  ''comment out then OK
    print "starter"
    dim as udt u
    u.show
    sleep
    end sub
 
Comment out init then OK.
use my previous dll caller.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Constructor in dll

Post by deltarho[1859] »

Thanks srvaldez
The post following your link questions the need for Dllmain and gives examples pretty much like fxm. Wow, that was an old thread. <smile>

I have just realized that a couple of statements at the beginning of the dll code are being executed but are not within a Constructor Sub so it seems that a dll is not as passive as I thought. I must check that out.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Constructor in dll

Post by Josep Roca »

> Obviously, there is something inside InitializeCryptoBuffers which is problematic.

You bet. Calling API functions that require DLLs other than Kernel32.dll may result in problems that are difficult to diagnose. It doesn't matter if you are using a FB constructor, DllMain or PowerBasic's LibMain: from a DLL entry point, it's only safe to call Kernel32.dll (and not all of its functions).
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Constructor in dll

Post by deltarho[1859] »

dodicat wrote:If another sub is called from the constructor sub, then that other sub won't yet have actually been created, it needs to wait for the constructor sub to have run it's course.
I am using this in my PCG32II:

Code: Select all

Constructor pcg32
  This.MyRandomize
  This.GetSnapshot
End Constructor
without issue.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Constructor in dll

Post by fxm »

When a dll is loaded, the dll main code is executed after the dll constructors.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Constructor in dll

Post by deltarho[1859] »

Thanks José.

I have now given up. Executing InitializeCryptoBuffers at the beginning of PB code is no big deal but I can see some folk forgetting to do that and then asking me why their PB app just closes. I have forgotten myself and I wrote it. <laugh>
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Constructor in dll

Post by dodicat »

edit

Test dll.
depends what is inside init.
gfx instructions seem to fail
api functions seem OK

Code: Select all

'tester.bas
'compile -dll
#include "windows.bi"
type udt
    as zstring * 20 y
    as integer n
    declare constructor
    declare destructor
    declare sub show
end type


constructor udt export
y="The year is: "
n=2019
end constructor

destructor udt export
print "Nothing to destroy"
sleep 1000
end destructor

sub udt.show export
    print y;n
end sub

sub init
  messagebox(0,"Inside "+__function__,"HELLO",0)
  type<udt>.show
    end sub

sub dothis constructor 
    
     print "starter "+__function__
    init  
end sub


 
Last edited by dodicat on May 03, 2019 22:06, edited 1 time in total.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Constructor in dll

Post by deltarho[1859] »

@dodicat

"it fails because InitializeCryptoBuffers has yet to be created."

You mentioned that earlier but what do you mean by "has yet to be created"?
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Constructor in dll

Post by dodicat »

I was mistaken deltarho.
The gfx screen 8 failed, but other instructions are OK inside init.
Probably the same for your init sub, some instructions fail, some are OK.
I have adjusted the code above.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Constructor in dll

Post by deltarho[1859] »

There is some pretty heavy-duty stuff going on in InitializeCryptoBuffers, using a subset of the available threadpool APIs. I am nothing like as well-read on this subject as I would like to be but I suspect that

Code: Select all

WaitForThreadpoolWorkCallbacks(Work0,FALSE)
WaitForThreadpoolWorkCallbacks(Work0plus,FALSE)
dislike being in a Constructor environment. There again it may be something else.

On a side note, at the very beginning of InitializeCryptoBuffers, before any of the exported procedures, I inserted ' Print "I'm here" '. "I'm here" got printed followed by the execution of an exported Function. So, dlls, without Constructor/Destructor, are not passive modules as I thought they were. At least they are not passive in FreeBASIC, I am not sure I could get a PowerBASIC dll to print anything by just inserting a statement. The entry point to exes and dlls are different at the source level for PowerBASIC and FreeBASIC although, ultimately, they will be the same on compiling.
Post Reply