No way to specify DllMain in DLL projects in Silver

windows
silver

#1

IDE: Visual Studio 2015
Version: 10.0.2255
Target: Island(Windows 32-bit)
Description:

When creating a DLL in Silver (for example by creating a command line application and changing the Executeble Type from Exe to Library) there is no way that I could find to specify DllMain.

Statements at file scope aren’t executed at all (RemObjects.Elements.System.<global>::Main doesn’t get called) l which is kinda good, but there still needs to be a way to define a DllMain function.


(Carlo Kok) #2

If you look at IslandRTL I do implement dllmainstartup:


method ExternalCalls.DllMainCRTStartup(aModule: rtl.HMODULE; aReason: rtl.DWORD; aReserved: ^Void): Boolean;
begin
  fModuleHandle := aModule;
  var m: VoidMethod;
  if aReason = rtl.DLL_PROCESS_ATTACH then begin
    m := @DllEntry;
    if assigned(m) then m();
  end;
  if aReason = rtl.DLL_PROCESS_ATTACH then
    m := @DllExit;
    if assigned(m) then m();
  exit true;
end;

You should be able to override these two:

    [SymbolName('__elements_dll_entry'), &Weak]
    class method DllEntry;  external;
    [SymbolName('__elements_dll_exit'), &Weak]
    class method DllExit;  external;

(By defining non weak static methods with no arguments with those symbol names)

Never tried this myself though.


Global initialization is not thread-safe (especially in DLLs) in Silver
#3

This works, but there are a couple of problems with this approach:

  1. We don’t get thread notifications (DLL_THREAD_ATTACH and DLL_THREAD_DETACH)
  2. We don’t get the HMODULE (possible to work around with GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, ...) but why should we have to?)
  3. We don’t get the lpvContext (lpvReserved) which officially differentiates between static and dynamic load and unofficially does a lot more, which can’t be worked around.

The convoluted way to solve this is to add two more function for thread callbacks. The simple way would be to simply forward the 3 parameters to a single DllMain function and let the programmer do the if/switch on the fdwReason etc.


(RemObjects) #4

Thanks, logged as bugs://79750


(Carlo Kok) #5

I’ll see what I can do. The trickiest part is how to solve this cleanly really.


#6

As I said, I think the best would be something along the lines of:

[SymbolName('__elements_dllmain'), &Weak]
class method DllMain(aModule: rtl.HMODULE; aReason: rtl.DWORD; aReserved: ^Void): Boolean; external;

type DllMainType = method (aModule: rtl.HMODULE; aReason: rtl.DWORD; aReserved: ^Void): Boolean;

method ExternalCalls.DllMainCRTStartup(aModule: rtl.HMODULE; aReason: rtl.DWORD; aReserved: ^Void): Boolean;
begin
  { Any RTL initialization required (currently seems there is none), and then: }
  var m: DllMainType := @DllMain;
  if assigned(m) then exit m(aModule, aReason, aReserved);
  exit true;
end;

Ignore any obvious syntax errors. I did my best. :slight_smile:


(Carlo Kok) #7

Yep; something like that.


(Carlo Kok) #8

See my latest push on islandRTL; (which you should be able to grab locally)


(RemObjects) #9

bugs://79750 got closed with status fixed.