Author Topic: $DLL issue  (Read 2008 times)

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
$DLL issue
« on: November 03, 2020, 05:24:47 PM »
Using the help file example so I can have my own DllMain my bcxpp.dll fails to function as it should
If I let BCX add the DllMain every thing functions.


This is the translation of the help file example for $NODLLMAIN
Bcx basic
Code: [Select]
-------------------------------------------------------------------------
FUNCTION DllMain(hInst AS HINSTANCE, _
                     Reason AS DWORD, _
                  Reserved AS LPVOID) EXPORT

   SELECT CASE Reason
     '**************************************************************
   CASE DLL_PROCESS_ATTACH
     ' < -- Do our initializations here  -- >
     MSGBOX "Your DLL has been loaded"
     '**************************************************************
   CASE DLL_PROCESS_DETACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH
   END SELECT
 
   FUNCTION = TRUE
 END FUNCTION
---------------------------------------------------------------------
translation
Code: [Select]
C_EXPORT int __stdcall DllMain (HINSTANCE  hInst, DWORD Reason, LPVOID  Reserved)
{
    if(Reason == DLL_PROCESS_ATTACH ) {
        MessageBox (GetActiveWindow(), "Your DLL has been loaded", "", 0 );
        goto L1003;
    }
    if(Reason == DLL_PROCESS_DETACH || Reason == DLL_THREAD_ATTACH || Reason == DLL_THREAD_DETACH ) {
    }
L1003:
    ;
    return TRUE;
}





This is what Bcx Adds if there is no $NODLLMAIN
Code: [Select]
__declspec(dllexport) BOOL WINAPI DllMain (HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
    UprCase = (unsigned char*)calloc(257, 1), UprCase = MakeUCaseTbl();

    switch (Reason)
    {
    case DLL_PROCESS_ATTACH:
        BCX_hInstance = hInst;
        break;
    case DLL_PROCESS_DETACH:
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

James

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: $DLL issue
« Reply #1 on: November 03, 2020, 07:11:17 PM »
I have a private app from 2002 that starts like this:

$NODLLMAIN    ' < -- $NODLLMAIN MUST appear before the $DLL statement
$DLL STDCALL  ' < -- Create a standard 32bit Windows DLL

My DllMain is coded thusly:

FUNCTION DllMain(hInst AS HINSTANCE,Reason AS DWORD,Reserved AS LPVOID)  EXPORT

And a  function that registers a custom control is coded thusly:

FUNCTION Register_Brick ( hInst as HINSTANCE)  EXPORT

It translates with 761, compiles 32 & 64 using Pelles v10, and (seemingly) runs as it should.

 

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: $DLL issue
« Reply #2 on: November 03, 2020, 08:43:47 PM »
JC,

In an experiment, I added the following at the end of SUB Final_Tweaks (Source$)

  REPLACE "C_EXPORT int __stdcall DllMain" _
  WITH    "__declspec(dllexport) BOOL WINAPI DllMain " IN Source$



This will emit textbook MS versions of the DllMain prototype and function declaration.

It didn't change my results but maybe it will change yours.

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: $DLL issue
« Reply #3 on: November 04, 2020, 06:26:36 AM »
Kevin,
  I tried your fix but it still fails.
My dll is c++ 64bit code. there is another wrinkle I just noticed (note this works)
My code:
Code: [Select]
$CCODE
__declspec(dllexport) BOOL WINAPI DllMain (HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
    switch (Reason)
    {
    case DLL_PROCESS_ATTACH:
        printf("%s\n", "'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*");
        printf("%s\n", "                   jcf bcxpp.dll version 1.0.2 has loaded");
        printf("%s\n", "'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*");
        break;
    case DLL_PROCESS_DETACH:
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

$CCODE
'==============================================================================
But. BCX Adds a couple of goodies even to MY $CCODE wrapped c/c++ code.
// *************************************************
//                System Variables
// *************************************************
static  unsigned char*  UprCase;
and
 UprCase = (unsigned char*)calloc(257, 1), UprCase = MakeUCaseTbl();
Again note this works.
Code: [Select]
// *************************************************
//                System Variables
// *************************************************

static  unsigned char*  UprCase;
//------------------------------------------------------------------------------
__declspec(dllexport) BOOL WINAPI DllMain (HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
    UprCase = (unsigned char*)calloc(257, 1), UprCase = MakeUCaseTbl();

    switch (Reason)
    {
    case DLL_PROCESS_ATTACH:
        printf("%s\n", "'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*");
        printf("%s\n", "                   jcf bcxpp.dll version 1.0.2 has loaded");
        printf("%s\n", "'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*");
        break;
    case DLL_PROCESS_DETACH:
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}


To continue this saga I found this works. Note I added AS BOOL per MSDN ( yeah anal I know)

Code: [Select]
FUNCTION DllMain(hInst AS HINSTANCE, Reason AS DWORD, Reserved AS LPVOID) AS BOOL EXPORT

    SELECT CASE Reason
     '**************************************************************
        CASE DLL_PROCESS_ATTACH
     
            ! UprCase = (unsigned char*)calloc(257, 1), UprCase = MakeUCaseTbl();
     
            ? "'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*"
            ? "                       jcf bcxpp.dll version 1.0.1 has loaded"
            ? "'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*"
     '**************************************************************
       CASE DLL_PROCESS_DETACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH
    END SELECT
 
    FUNCTION = TRUE
END FUNCTION


I am using iReplace in my ProcessLine Function and I guess this is why it failed?
adding ! UprCase = (unsigned char*)calloc(257, 1), UprCase = MakeUCaseTbl();
fixed it. Try adding iReplace in your ProcessLine BcxPP.dll source and see if it fails.

I am not sure how to code:
! UprCase = (unsigned char*)calloc(257, 1), UprCase = MakeUCaseTbl();
In Bcx

James
 

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: $DLL issue
« Reply #4 on: November 04, 2020, 08:41:25 AM »
JC,

Lots to unpack in your note.

1) You said your DLL is C++ 64bit code.  C++ name mangles, C does not.
   
2) UprCase = (unsigned char*)calloc(257, 1), UprCase = MakeUCaseTbl();
                                and
   LwrCase = (unsigned char*)calloc(257, 1), LwrCase = MakeLCaseTbl();

   are BCX system requirements used by UCASE$, LCASE$, and other runtime
   functions that require them.  Contrary to what you want to believe,
   $CCODE does not mean "keep your grubby mitts off my code", it means
   treat this code as C/C++ not BASIC.

3) You said, "I am using iReplace in my ProcessLine Function and I guess this is why it failed?"

   I say that is incorrect.

   You said, "Try adding iReplace in your ProcessLine BcxPP.dll source and see if it fails"

  I did.  It translates, compiles and runs correctly. 
  And yes, BCX added the line from #2 as IREPLACE depends on it via _stristr_.



  FUNCTION ProcessLine (Src$) AS LONG EXPORT
    IF Src$ = "DISPLAY MESSAGE" THEN Src$ = "PRINT " + ENC$("MAGIC HAPPENS")
 
    DIM a$
    IREPLACE "this" with "that" in a$

   
    FUNCTION = 1
  END FUNCTION



My hunch is that BCX is not responsible for why your code is failing.

[FAILING CODE NOT SHOWN]

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: $DLL issue
« Reply #5 on: November 04, 2020, 10:58:36 AM »
Kevin,
  Ask and you shall receive.

James

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: $DLL issue
« Reply #6 on: November 04, 2020, 12:15:11 PM »
JC,

I successfully built from scratch bcxpp.dll using the NOT WORKING basic code.
 
Next I tried to translate vector_04c.bas,  I do get the loaded message:

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
                 jcf bcxpp.dll version 1.0.2 has loaded
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
BCXPP.DLL Successfully Loaded

but the translation fails on this line of vector_04c.bas

  RbFor ( auto itx : s)

The ball is back in your court.

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: $DLL issue
« Reply #7 on: November 04, 2020, 12:46:53 PM »
Did you try building with the working code?
The bcxpp.dll builds fine with both. It just barfs with the not working bcxpp when it encounters the RbFor.
It should be fine with the working code.

Build the dll with the working code and it should handle the Rbfor.

James


MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: $DLL issue
« Reply #8 on: November 04, 2020, 12:55:43 PM »
I get what's happening now ... I used WinMerge on your two .bas files.

If you comment the following lines out, the table is never initialized and when used
in ProcessLine via IREPLACE --_stricmp_ --  kablooey.

  UprCase = (PUCHAR)calloc(257, 1)
  UprCase = MakeUCaseTbl()


So the fix will entail BCX adding those dependencies to DllMain when needed.

That should not be too difficult to pull off.  I'm on it ...

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: $DLL issue
« Reply #9 on: November 04, 2020, 01:49:18 PM »
JC,

Give this a go.   BCX should automatically emit the Upr and Lwr case table setup in DLL's, only when needed.

 Replace line 4205 in 761

IF LEFTSTR(LZZ$,"int main") OR LEFTSTR(LZZ$,"int WINAPI WinMain") OR LEFTSTR(LZZ$,"__declspec(dllexport) BOOL WINAPI DllMain") THEN


WITH THIS:


 IF LEFTSTR(LZZ$,"int main") _
  OR LEFTSTR(LZZ$,"int WINAPI WinMain") _
  OR LEFTSTR(LZZ$,"__declspec(dllexport) BOOL WINAPI DllMain") _
  OR LIKE (LZZ$,"*__stdcall*DllMain*(HINSTANCE *,*") THEN

The "LIKE" clause should work in most situations -- time will tell...

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: $DLL issue
« Reply #10 on: November 04, 2020, 02:16:28 PM »
Kevin,
   That was fast and it works too.
Great Job!!

James


Robert

  • Hero Member
  • *****
  • Posts: 1142
    • View Profile
Re: $DLL issue
« Reply #11 on: November 04, 2020, 02:21:38 PM »
JC,

Give this a go.   BCX should automatically emit the Upr and Lwr case table setup in DLL's, only when needed.

 Replace line 4205 in 761

IF LEFTSTR(LZZ$,"int main") OR LEFTSTR(LZZ$,"int WINAPI WinMain") OR LEFTSTR(LZZ$,"__declspec(dllexport) BOOL WINAPI DllMain") THEN


WITH THIS:


 IF LEFTSTR(LZZ$,"int main") _
  OR LEFTSTR(LZZ$,"int WINAPI WinMain") _
  OR LEFTSTR(LZZ$,"__declspec(dllexport) BOOL WINAPI DllMain") _
  OR LIKE (LZZ$,"*__stdcall*DllMain*(HINSTANCE *,*") THEN

The "LIKE" clause should work in most situations -- time will tell...

Really! A most excellent detection by James of yet another obscure corner case.

And, as usual, a superb elegant resolution by MrBCX.

Thank you.