1. Where is my DLL?

Hi all,

how can a DLL find the path where it was loaded from?
I need it because the DLL must read an INI file that is in the same
directory as the DLL. Of course I don't know, where the users will
install it.

command_line() is of no use here, because when calling it from a DLL the
return value obviously is an empty sequence.
The Win32 API function GetModuleFileName() came to my mind. But if I
pass NULL to it as the module handle parameter, the function returns
the path of the EXE file that has called the DLL.

Somewhere on the internet I read:
| If you want to find the path for a DLL, pass the DLLs instance handle,
| which you can obtain from the first parameter in your DLL's DLLMain()
| function.

Of course in Euphoria there is no DLLMain() function.
When I pass the result of Euphoria's instance() function as the module
handle parameter, GetModuleFileName() also returns the path of the EXE
file instead the path of the DLL.

Then I found the API function GetModuleHandle(). This gives me the
handle of a module, so that I can find its name. As parameter,
GetModuleHandle() requires the name of the module ... smile)

Well, that name does not have to specify a path, so this might work to
some degree. E.g. I can pass "my.dll" to GetModuleHandle(), than pass
the handle to GetModuleFileName(), and as result I'll get e.g.
"C:\this\and\that\my.dll".

This not only seems somewhat crazy to me smile, I think there can be at
least two problems:
a) If the user renames the DLL, GetModuleHandle() will not return its
   handle any more.

b) If the name does not include a path and there is more than one
   loaded module with the same base name and extension, you cannot
   predict which module handle will be returned.
   [MSDN Library]


What can I do? Thanks in advance for any hints.

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » topic index » view message » categorize

2. Re: Where is my DLL?

Why don't you let the .exe and the .dll in the same directory ?
It could simplify all your problems.
Except if the .dll has to be used by another .exe that will be in other
 directory, it could be simple.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Where is my DLL?

Juergen Luethje wrote:
> 
> Hi all,
> 
> how can a DLL find the path where it was loaded from?
> I need it because the DLL must read an INI file that is in the same
> directory as the DLL. Of course I don't know, where the users will
> install it.
> 
> command_line() is of no use here, because when calling it from a DLL the
> return value obviously is an empty sequence.
> The Win32 API function GetModuleFileName() came to my mind. But if I
> pass NULL to it as the module handle parameter, the function returns
> the path of the EXE file that has called the DLL.
> 
> Somewhere on the internet I read:
> | If you want to find the path for a DLL, pass the DLLs instance handle,
> | which you can obtain from the first parameter in your DLL's DLLMain()
> | function.
> 
> Of course in Euphoria there is no DLLMain() function.
> When I pass the result of Euphoria's instance() function as the module
> handle parameter, GetModuleFileName() also returns the path of the EXE
> file instead the path of the DLL.
> 
> Then I found the API function GetModuleHandle(). This gives me the
> handle of a module, so that I can find its name. As parameter,
> GetModuleHandle() requires the name of the module ... smile)
> 
> Well, that name does not have to specify a path, so this might work to
> some degree. E.g. I can pass "my.dll" to GetModuleHandle(), than pass
> the handle to GetModuleFileName(), and as result I'll get e.g.
> "C:\this\and\that\my.dll".
> 
> This not only seems somewhat crazy to me smile, I think there can be at
> least two problems:
> a) If the user renames the DLL, GetModuleHandle() will not return its
>    handle any more.
> 
> b) If the name does not include a path and there is more than one
>    loaded module with the same base name and extension, you cannot
>    predict which module handle will be returned.
>    [MSDN Library]
> 
> 
> What can I do? Thanks in advance for any hints.
> 
> Regards,
>    Juergen
> 
> -- 
> Have you read a good program lately?
> 
> 

Juergen:

Either install the dll with it's location specified in the registry
or place it in the system directory.
The only way to prevent the user from renaming it is to
make the dll read only so the user will realize that he should
not be renaming it.

Bernie

My files in archive:
w32engin.ew mixedlib.e eu_engin.e win32eru.exw

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

new topic     » goto parent     » topic index » view message » categorize

4. Re: Where is my DLL?

DominiqueB wrote:

> Why don't you let the .exe and the .dll in the same directory ?
> It could simplify all your problems.
> Except if the .dll has to be used by another .exe that will be in other
>  directory, it could be simple.

I only distribute the DLL. I don't know where the user puts it, and
I don't know where the user has put the EXE file that calls the DLL.

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

5. Re: Where is my DLL?

Juergen Luethje wrote:
> 
> Hi all,
> 
> how can a DLL find the path where it was loaded from?
> I need it because the DLL must read an INI file that is in the same
> directory as the DLL. Of course I don't know, where the users will
> install it.
> 
> command_line() is of no use here, because when calling it from a DLL the
> return value obviously is an empty sequence.
> The Win32 API function GetModuleFileName() came to my mind. But if I
> pass NULL to it as the module handle parameter, the function returns
> the path of the EXE file that has called the DLL.
> 
> Somewhere on the internet I read:
> | If you want to find the path for a DLL, pass the DLLs instance handle,
> | which you can obtain from the first parameter in your DLL's DLLMain()
> | function.
> 
> Of course in Euphoria there is no DLLMain() function.
> When I pass the result of Euphoria's instance() function as the module
> handle parameter, GetModuleFileName() also returns the path of the EXE
> file instead the path of the DLL.
> 
> Then I found the API function GetModuleHandle(). This gives me the
> handle of a module, so that I can find its name. As parameter,
> GetModuleHandle() requires the name of the module ... smile)
> 
> Well, that name does not have to specify a path, so this might work to
> some degree. E.g. I can pass "my.dll" to GetModuleHandle(), than pass
> the handle to GetModuleFileName(), and as result I'll get e.g.
> "C:\this\and\that\my.dll".
> 
> This not only seems somewhat crazy to me smile, I think there can be at
> least two problems:
> a) If the user renames the DLL, GetModuleHandle() will not return its
>    handle any more.
> 
> b) If the name does not include a path and there is more than one
>    loaded module with the same base name and extension, you cannot
>    predict which module handle will be returned.
>    [MSDN Library]
> 
> 
> What can I do? Thanks in advance for any hints.
> 
> Regards,
>    Juergen
> 
> -- 
> Have you read a good program lately?
> 
> 

Hello there,


Perhaps you can simply send the path to a function in the dll from
the .exe file that loaded it.


Take care,
Al

And, good luck with your Euphoria programming!

My bumper sticker: "I brake for LED's"

new topic     » goto parent     » topic index » view message » categorize

6. Re: Where is my DLL?

Bernie Ryan wrote:

> Juergen Luethje wrote:
>>
>> Hi all,
>>
>> how can a DLL find the path where it was loaded from?
>> I need it because the DLL must read an INI file that is in the same
>> directory as the DLL. Of course I don't know, where the users will
>> install it.

<snip>

>> This not only seems somewhat crazy to me smile, I think there can be at
>> least two problems:
>> a) If the user renames the DLL, GetModuleHandle() will not return its
>>    handle any more.
>>
>> b) If the name does not include a path and there is more than one
>>    loaded module with the same base name and extension, you cannot
>>    predict which module handle will be returned.
>>    [MSDN Library]
>>
>>
>> What can I do? Thanks in advance for any hints.

<snip>

> Juergen:
>
> Either install the dll with it's location specified in the registry
> or place it in the system directory.

Unfortunately, the installation process is not under my control.
It would probably not even have much effect when I recommend the user to
put the DLL into this or that directory.
The DLL is a plugin for Total Commander (TC). Many users have dozens of
plugins, and many people have their own system how to organize the
plugins.
The user can install the plugin manually, or by using a semi-automatical
procedure provided by TC. In any case, TC writes the location of the
plugin into its own INI file. But I also don't know where TC's INI file
is on a given machine.

> The only way to prevent the user from renaming it is to
> make the dll read only so the user will realize that he should
> not be renaming it.

I just tested it, making the DLL read-only, system, and hidden.
Renaming was easy, it worked the same way as without these attributes
(using Total Commander on Windows 98).

Maybe the risk that someone will rename the DLL is not soooo high.
However, I would highly prefer that renaming it would not influence
its functionality.

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

7. Re: Where is my DLL?

Me wrote:

<snip>

> Somewhere on the internet I read:
>| If you want to find the path for a DLL, pass the DLLs instance handle,
>| which you can obtain from the first parameter in your DLL's DLLMain()
>| function.
>
> Of course in Euphoria there is no DLLMain() function.
> When I pass the result of Euphoria's instance() function as the module
> handle parameter, GetModuleFileName() also returns the path of the EXE
> file instead the path of the DLL.

<snip>

Now I looked at the C code produced by the translator.
In main_.c it reads:

<C code>
int __declspec (dllexport) __stdcall DllMain(int hDLL, int Reason, void
*Reserved)
{
    if (Reason == 1)
        EuInit();
    return 1;
}
</C code>

Maybe it's possible to manually add some C code that fetches the value
of 'hDLL', so that I can use it in my Euphoria code? The problem is that
I know almost nothing about C. Can someone tell me how to do so?

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

8. Re: Where is my DLL?

Al Getz wrote:

<big snip>

> Perhaps you can simply send the path to a function in the dll from
> the .exe file that loaded it.

Unfortunately that is not possible because that EXE file is not written
by me.

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

9. Re: Where is my DLL?

Juergen:

   If you go to the registry and find the location of Total Commander;
   then you should be able to locate where the TC ini file is.
   From the ini file you will then know where the user's plugins
   are located.

Bernie

My files in archive:
w32engin.ew mixedlib.e eu_engin.e win32eru.exw

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

new topic     » goto parent     » topic index » view message » categorize

10. Re: Where is my DLL?

> how can a DLL find the path where it was loaded from?
> Somewhere on the internet I read:
> | If you want to find the path for a DLL, pass the DLLs instance handle,
> | which you can obtain from the first parameter in your DLL's DLLMain()
> | function.
>
> Of course in Euphoria there is no DLLMain() function.

When you create your DLL using "DLL_PROCESS_ATTACH", etc, this is! your
DLLMain() function, though some call it LibMain(), or whatever...
...and the function's first parameter can be used to call
GetModuleFileName(), I'd guess.
This might be another round-about way... as an example.

include dll.e
include machine.e
include misc.e
constant
 k32=open_dll("kernel32.dll")
,GetModuleFileName=define_c_func(k32,"GetModuleFileNameA",{C_UINT,C_POINTER,
C_INT},C_UINT)
atom path, ret
sequence name
path=allocate(256+266)
ret=c_func(GetModuleFileName,{k32,path,256+266})
name=peek({path,ret})
printf(1,"%s\n",{name})
sleep(3)

new topic     » goto parent     » topic index » view message » categorize

11. Re: Where is my DLL?

Me wrote:

> Me wrote:
>
> <snip>
>
>> Somewhere on the internet I read:
>>| If you want to find the path for a DLL, pass the DLLs instance handle,
>>| which you can obtain from the first parameter in your DLL's DLLMain()
>>| function.
>>
>> Of course in Euphoria there is no DLLMain() function.
>> When I pass the result of Euphoria's instance() function as the module
>> handle parameter, GetModuleFileName() also returns the path of the EXE
>> file instead the path of the DLL.
>
> <snip>
>
> Now I looked at the C code produced by the translator.
> In main_.c it reads:
>
> <C code>
> int __declspec (dllexport) __stdcall DllMain(int hDLL, int Reason, void
> *Reserved)
> {
>     if (Reason == 1)
>         EuInit();
>     return 1;
> }
> </C code>
>
> Maybe it's possible to manually add some C code that fetches the value
> of 'hDLL', so that I can use it in my Euphoria code? The problem is that
> I know almost nothing about C. Can someone tell me how to do so?

I looks as if I've got it! smile)

In my Eu program, I just defined a variable
    global atom DLL_Instance

Although I did not assign a value to the variable, I could use it in my
program, and the program translated without error. Then after translation,
I added one line to the above function:

<C code>
int __declspec (dllexport) __stdcall DllMain(int hDLL, int Reason, void
*Reserved)
{
    _1DLL_Instance = hDLL;

    if (Reason == 1)
        EuInit();
    return 1;
}
</C code>

Rob, it looks as if it would be not much work to implement a
function dll_instance() in the next Euphoria relase. Pleeease. smile

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

12. Re: Where is my DLL?

------=_Part_6105_30208978.1129445345663
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Content-Disposition: inline

Maybe I'm missing something but isn't this an example of when the windows
registry comes in handy? You can store and retrieve info about your program
without having to know where your program is running from?

Just my tuppence worth :)

Jess

--
Do something useful with your PC
http://www.grid.org/projects/

------=_Part_6105_30208978.1129445345663
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Content-Disposition: inline

Maybe I'm missing something but isn't this an example of when the
windows registry comes in handy? You can store and retrieve info about
your program without having to know where your program is running from?<br><br
clear="all">Just my tuppence worth :)<br>
<br>
Jess<br>
<br>-- <br>Do something useful with your PC<br><a
href="http://www.grid.org/projects/">http://www.grid.org/projects/</a>

------=_Part_6105_30208978.1129445345663--

new topic     » goto parent     » topic index » view message » categorize

13. Re: Where is my DLL?

Juergen Luethje wrote:
> Rob, it looks as if it would be not much work to implement a
> function dll_instance() in the next Euphoria relase. Pleeease. smile

OK, I'll look into it.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

14. Re: Where is my DLL?

Robert Craig wrote:

> Juergen Luethje wrote:
>
>> Rob, it looks as if it would be not much work to implement a
>> function dll_instance() in the next Euphoria relase. Pleeease. smile
>
> OK, I'll look into it.

Thanks for doing so!

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

15. Re: Where is my DLL?

Wolf wrote:

>> how can a DLL find the path where it was loaded from?
>> Somewhere on the internet I read:
>>| If you want to find the path for a DLL, pass the DLLs instance handle,
>>| which you can obtain from the first parameter in your DLL's DLLMain()
>>| function.
>>
>> Of course in Euphoria there is no DLLMain() function.
>
> When you create your DLL using "DLL_PROCESS_ATTACH", etc, this is! your
> DLLMain() function, though some call it LibMain(), or whatever...

I don't know what DLL_PROCESS_ATTACH is. (And the problem here is, that
I don't know much about C at all.)
However, I've seen now that Eu code translated for Borland has a function
    DllMain()
and Eu code translated for Watcom has a function
    LibMain().

> ...and the function's first parameter can be used to call
> GetModuleFileName(), I'd guess.

Yes. Now I've found a (hopefully correct) way to fetch the value of that
parameter, so that I can use it in my Eu DLL.
I wrote the following small include file:

--------------------------[ dll_instance.e ]--------------------------
atom DLL_Instance
-- DLL_Instance = 0             -- Initialize the variable only when
                                -- testing the program with the
                                -- interpreter, *not* when compiling
                                -- to a DLL!
global function dll_instance()
   return DLL_Instance
end function

----------------------------------------------------------------------

I include this file in the code of my DLL, and after translation,
in the file "main_.c" I add something like

    _2DLL_Instance = hDLL;

as the first line to either DllMain() or LibMain().
When dll_instance.e is not the 1st but the 2nd included file, then
the number must be not 2, but 3 etc. A small Eu program does it for me.

This seems to work fine so far. Unfortunately, I always have to
uncomment the line in the include file that initializes the variable
'DLL_Instance', before I can run the code with the interpreter.

Wolf, do you know a better way to get the value of the first parameter
of DllMain()/LibMain()? blink

<snip>

Thanks,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

16. Re: Where is my DLL?

Jess Harpur wrote:

> Maybe I'm missing something but isn't this an example of when the windows
> registry comes in handy? You can store and retrieve info about your program
> without having to know where your program is running from?

I can't store information in the registry, because the installation
process is not under my control.

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

17. Re: Where is my DLL?

> I can't store information in the registry, because the installation
> process is not under my control.

That doesn't matter. You can store data in the registry at any time,
regardles of whether or not the key was "installed" by the registry.

~Greg

new topic     » goto parent     » topic index » view message » categorize

18. Re: Where is my DLL?

Bernie Ryan wrote:

> Juergen:
>
>    If you go to the registry and find the location of Total Commander;
>    then you should be able to locate where the TC ini file is.
>    From the ini file you will then know where the user's plugins
>    are located.

Yes, that should work. Also commandline parameters of Total Commander,
environment variables and more must be taken into account. On the Total
Commander forum I found a recent discussion
    "Detect path to TC main settings file from plugin"

Funny, isn't it? smile There it is explained how to do it.

However, in the meantime I found another way how to get the location of
the DLL, using GetModuleFileName() (for details please see my reply to
Wolf). I think the function was made for that purpose.

I'm sorry, I believe I forgot to mention, that the DLL not only can be
used by Total Commander, but also by any other program. Although I think
probably not many people will use the DLL with their own program, I'd
prefer a solution that does not rely on information provided by Total
Commander.

So I'll first gather some experience with the other method. But it's
good to know an alternative way in case there will be problems.

Thanks,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

19. Re: Where is my DLL?

Greg,

please do not snip text of a message so that its sense gets distorted.
Thanks. In the following I've restored the complete text:

Greg Haberek wrote:

> Juergen Luethje wrote:
>>
>> Jess Harpur wrote:
>>
>>> Maybe I'm missing something but isn't this an example of when the windows
>>> registry comes in handy? You can store and retrieve info about your program
>>> without having to know where your program is running from?
>>
>> I can't store information in the registry, because the installation
>> process is not under my control.
>
> That doesn't matter. You can store data in the registry at any time,
> regardles of whether or not the key was "installed" by the registry.

Yes, I can store data in the registry at any time. Of course I was
meaning:
I can't store information *about the installation prozess* in the
registry, because it's not under my control.

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

20. Re: Where is my DLL?

Juergen Luethje wrote:
> 
> Bernie Ryan wrote:
> 
> > Juergen:
> >
> >    If you go to the registry and find the location of Total Commander;
> >    then you should be able to locate where the TC ini file is.
> >    From the ini file you will then know where the user's plugins
> >    are located.
> 
> Yes, that should work. Also commandline parameters of Total Commander,
> environment variables and more must be taken into account. On the Total
> Commander forum I found a recent discussion
>     "Detect path to TC main settings file from plugin"
> 
> Funny, isn't it? smile There it is explained how to do it.
> 
> However, in the meantime I found another way how to get the location of
> the DLL, using GetModuleFileName() (for details please see my reply to
> Wolf). I think the function was made for that purpose.
> 
> I'm sorry, I believe I forgot to mention, that the DLL not only can be
> used by Total Commander, but also by any other program. Although I think
> probably not many people will use the DLL with their own program, I'd
> prefer a solution that does not rely on information provided by Total
> Commander.
> 
> So I'll first gather some experience with the other method. But it's
> good to know an alternative way in case there will be problems.
> 

I think the 'correct' windows behavior is to store this type of information
in the "\Documents and Settings\username\Application\appname\" directory.
Be careful about trying to write to the same location as the dll, because 
this can cause problems if the user doesn't have write permission to the
directory (i.e., if they are trying to run as non-administrator).  Not 
that a lot of apps don't already make you run as admin...

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

21. Re: Where is my DLL?

Matt Lewis wrote:

<snip>

> I think the 'correct' windows behavior is to store this type of information
> in the "\Documents and Settings\username\Application\appname\" directory.
> Be careful about trying to write to the same location as the dll, because
> this can cause problems if the user doesn't have write permission to the
> directory (i.e., if they are trying to run as non-administrator).  Not
> that a lot of apps don't already make you run as admin...

Currently the DLL only reads from a file (which contains the text for
dialog boxes and messages in the appropriate language).
But in the next version, the DLL might also write to a file. I'll save
your information in my concerning project folder, so that I have it at
hand when I'm writing the next release of the program. smile

Thanks,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

22. Re: Where is my DLL?

Me wrote:

[How can a DLL written in Euphoria get its own instance handle?]

<snip>

> Now I've found a (hopefully correct) way to fetch the value of
> [the first parameter of DllMain()/LibMain()] so that I can use
> it in my Eu DLL.
> I wrote the following small include file:
>
> --------------------------[ dll_instance.e ]--------------------------
> }}}
<eucode>
> atom DLL_Instance
> -- DLL_Instance = 0             -- Initialize the variable only when
>                                 -- testing the program with the
>                                 -- interpreter, *not* when compiling
>                                 -- to a DLL!
> global function dll_instance()
>    return DLL_Instance
> end function
> </eucode>
{{{

> ----------------------------------------------------------------------
>
> I include this file in the code of my DLL, and after translation,
> in the file "main_.c" I add something like
>
>     _2DLL_Instance = hDLL;
>
> as the first line to either DllMain() or LibMain().
> When dll_instance.e is not the 1st but the 2nd included file, then
> the number must be not 2, but 3 etc. A small Eu program does it for me.
>
> This seems to work fine so far. Unfortunately, I always have to
> uncomment the line in the include file that initializes the variable
> 'DLL_Instance', before I can run the code with the interpreter.

<snip>

Rob, I just thought that I'd sleep better if you could confirm that I'm
not doing something potentially dangerous here. smile

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

23. Re: Where is my DLL?

Juergen Luethje wrote:
> 
> Me wrote:
> 
> [How can a DLL written in Euphoria get its own instance handle?]
> 
> <snip>
> 
> > Now I've found a (hopefully correct) way to fetch the value of
> > [the first parameter of DllMain()/LibMain()] so that I can use
> > it in my Eu DLL.
> > I wrote the following small include file:
> >
> > --------------------------[ dll_instance.e ]--------------------------
> > }}}
<eucode>
> > atom DLL_Instance
> > -- DLL_Instance = 0             -- Initialize the variable only when
> >                                 -- testing the program with the
> >                                 -- interpreter, *not* when compiling
> >                                 -- to a DLL!
> > global function dll_instance()
> >    return DLL_Instance
> > end function
> > </eucode>
{{{

> > ----------------------------------------------------------------------
> >
> > I include this file in the code of my DLL, and after translation,
> > in the file "main_.c" I add something like
> >
> >     _2DLL_Instance = hDLL;
> >
> > as the first line to either DllMain() or LibMain().
> > When dll_instance.e is not the 1st but the 2nd included file, then
> > the number must be not 2, but 3 etc. A small Eu program does it for me.
> >
> > This seems to work fine so far. Unfortunately, I always have to
> > uncomment the line in the include file that initializes the variable
> > 'DLL_Instance', before I can run the code with the interpreter.
> 
> <snip>
> 
> Rob, I just thought that I'd sleep better if you could confirm that I'm
> not doing something potentially dangerous here. smile

I'm not sure. If hDLL is greater than a 31-bit integer 
there will be trouble, since Euphoria requires it to be 
stored in floating-point form. You might need to call 
my C routine NewDouble() to create a proper Euphoria atom 
in floating-point form.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

24. Re: Where is my DLL?

Robert Craig wrote:

> Juergen Luethje wrote:
>>
>> Me wrote:
>>
>> [How can a DLL written in Euphoria get its own instance handle?]
>>
>> <snip>
>>
>>> Now I've found a (hopefully correct) way to fetch the value of
>>> [the first parameter of DllMain()/LibMain()] so that I can use
>>> it in my Eu DLL.
>>> I wrote the following small include file:
>>>
>>> --------------------------[ dll_instance.e ]--------------------------
>>> }}}
<eucode>
>>> atom DLL_Instance
>>> -- DLL_Instance = 0             -- Initialize the variable only when
>>>                                 -- testing the program with the
>>>                                 -- interpreter, *not* when compiling
>>>                                 -- to a DLL!
>>> global function dll_instance()
>>>    return DLL_Instance
>>> end function
>>> </eucode>
{{{

>>> ----------------------------------------------------------------------
>>>
>>> I include this file in the code of my DLL, and after translation,
>>> in the file "main_.c" I add something like
>>>
>>>     _2DLL_Instance = hDLL;
>>>
>>> as the first line to either DllMain() or LibMain().
>>> When dll_instance.e is not the 1st but the 2nd included file, then
>>> the number must be not 2, but 3 etc. A small Eu program does it for me.
>>>
>>> This seems to work fine so far. Unfortunately, I always have to
>>> uncomment the line in the include file that initializes the variable
>>> 'DLL_Instance', before I can run the code with the interpreter.
>>
>> <snip>
>>
>> Rob, I just thought that I'd sleep better if you could confirm that I'm
>> not doing something potentially dangerous here. smile
>
> I'm not sure. If hDLL is greater than a 31-bit integer
> there will be trouble, since Euphoria requires it to be
> stored in floating-point form. You might need to call
> my C routine NewDouble() to create a proper Euphoria atom
> in floating-point form.

I see, thanks. Unfortunately, I don't know how to do so. getlost
Matt, can I use make_atom() in this situation, or is it "only" for
parameters?

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

25. Re: Where is my DLL?

Juergen Luethje wrote:
> 
> Robert Craig wrote:
> 
> >
> > I'm not sure. If hDLL is greater than a 31-bit integer
> > there will be trouble, since Euphoria requires it to be
> > stored in floating-point form. You might need to call
> > my C routine NewDouble() to create a proper Euphoria atom
> > in floating-point form.
> 
> I see, thanks. Unfortunately, I don't know how to do so. getlost
> Matt, can I use make_atom() in this situation, or is it "only" for
> parameters?
> 

Yes, that should work.  make_atom() is basically the same code as NewDouble(),
IIRC.

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

26. Re: Where is my DLL?

Juergen Luethje wrote:

> Robert Craig wrote:
>
>> Juergen Luethje wrote:

<snip>

>>> Rob, I just thought that I'd sleep better if you could confirm
>>> that I'm not doing something potentially dangerous here. smile
>>
>> I'm not sure. If hDLL is greater than a 31-bit integer
>> there will be trouble, since Euphoria requires it to be
>> stored in floating-point form. You might need to call
>> my C routine NewDouble() to create a proper Euphoria atom
>> in floating-point form.
>
> I see, thanks. Unfortunately, I don't know how to do so. getlost
> Matt, can I use make_atom() in this situation, or is it "only" for
> parameters?

Sorry, I don't want to bother anyone. It's just that using the DLL
instance handle currently seems to be the perfect solution for me, and
its value is contained in my program -- I just can't access it. That
really drives me crazy. I feel like a dog that sees and smells fresh
meat, and then someone says: "No my dear, that's not for you." smile

Now I tested the following, which *seems* to work. I use this include
file in my Eu program:

--------------------------[ dll_instance.e ]--------------------------
integer DLL_Instance_Hi, DLL_Instance_Lo
-- DLL_Instance_Hi = 0           -- Initialize the variables only when
-- DLL_Instance_Lo = 0           -- testing the program with the
                                 -- interpreter, *not* when compiling
                                 -- to a DLL!
global function dll_instance()
   return DLL_Instance_Hi*#10000 + DLL_Instance_Lo
end function

----------------------------------------------------------------------


After translating the program for Borland, in "main_.c" I added two
lines to DllMain(), so that it looks like this:

int __declspec (dllexport) __stdcall DllMain(int hDLL, int Reason, void
*Reserved)
{
    _9DLL_Instance_Hi = (hDLL >> 16) & 0xFFFF;    // line added manually
    _9DLL_Instance_Lo = hDLL & 0xFFFF;            // line added manually
    if (Reason == 1)
        EuInit();
    return 1;
}

Could one of our experts please tell me whether this can be considered
safe?

Regards,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

27. Re: Where is my DLL?

Juergen Luethje wrote:
> 
> 
> Sorry, I don't want to bother anyone.

It's no bother.  If we didn't want to be bothered, we wouldn't read this
list. :)

> 
> Now I tested the following, which *seems* to work. I use this include
> file in my Eu program:
> 
> --------------------------[ dll_instance.e ]--------------------------
> }}}
<eucode>
> integer DLL_Instance_Hi, DLL_Instance_Lo
> -- DLL_Instance_Hi = 0           -- Initialize the variables only when
> -- DLL_Instance_Lo = 0           -- testing the program with the
>                                  -- interpreter, *not* when compiling
>                                  -- to a DLL!
> global function dll_instance()
>    return DLL_Instance_Hi*#10000 + DLL_Instance_Lo
> end function
> </eucode>
{{{

> ----------------------------------------------------------------------
> 
> 
> After translating the program for Borland, in "main_.c" I added two
> lines to DllMain(), so that it looks like this:
> 
> int __declspec (dllexport) __stdcall DllMain(int hDLL, int Reason, void
> *Reserved)
> {
>     _9DLL_Instance_Hi = (hDLL >> 16) & 0xFFFF;    // line added manually
>     _9DLL_Instance_Lo = hDLL & 0xFFFF;            // line added manually
>     if (Reason == 1)
>         EuInit();
>     return 1;
> }
> 
> Could one of our experts please tell me whether this can be considered
> safe?
> 

That should work, since you're guaranteed to have a valid 31-bit integer.
You could alternatively do this (which is what make_atom does):

if( (unsigned)hDLL > (unsigned)0x7fffffff)
  {  _9DLL_Instance = NewDouble( (double)(unsigned long) hDLL ); Ref(hDLL);}

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

28. Re: Where is my DLL?

Matt Lewis wrote:

> Juergen Luethje wrote:

<snip>

>> Could one of our experts please tell me whether this can be considered
>> safe?
>
> That should work, since you're guaranteed to have a valid 31-bit integer.

Fine.

> You could alternatively do this (which is what make_atom does):
>
> if( (unsigned)hDLL > (unsigned)0x7fffffff)
>   {  _9DLL_Instance = NewDouble( (double)(unsigned long) hDLL ); Ref(hDLL);}

I was not sure how to exactly use make_atom in this context. Now I see.
Thanks Matt!!!

Happy,
   Juergen

-- 
Have you read a good program lately?

new topic     » goto parent     » topic index » view message » categorize

29. Re: Where is my DLL?

Matt Lewis wrote:
> 
> Juergen Luethje wrote:
> > 
> > Sorry, I don't want to bother anyone.
> 
> It's no bother.  If we didn't want to be bothered, we wouldn't read this
> list. :)
> 
> > 
> > Now I tested the following, which *seems* to work. I use this include
> > file in my Eu program:
> > 
> > --------------------------[ dll_instance.e ]--------------------------
> > }}}
<eucode>
> > integer DLL_Instance_Hi, DLL_Instance_Lo
> > -- DLL_Instance_Hi = 0           -- Initialize the variables only when
> > -- DLL_Instance_Lo = 0           -- testing the program with the
> >                                  -- interpreter, *not* when compiling
> >                                  -- to a DLL!
> > global function dll_instance()
> >    return DLL_Instance_Hi*#10000 + DLL_Instance_Lo
> > end function
> > </eucode>
{{{

> > ----------------------------------------------------------------------
> > 
> > 
> > After translating the program for Borland, in "main_.c" I added two
> > lines to DllMain(), so that it looks like this:
> > 
> > int __declspec (dllexport) __stdcall DllMain(int hDLL, int Reason, void
> > *Reserved)
> > {
> >     _9DLL_Instance_Hi = (hDLL >> 16) & 0xFFFF;    // line added manually
> >     _9DLL_Instance_Lo = hDLL & 0xFFFF;            // line added manually
> >     if (Reason == 1)
> >         EuInit();
> >     return 1;
> > }
> > 
> > Could one of our experts please tell me whether this can be considered
> > safe?

Juergen, your multiplication code looks correct.

> That should work, since you're guaranteed to have a valid 31-bit integer.
> You could alternatively do this (which is what make_atom does):
> 
> if( (unsigned)hDLL > (unsigned)0x7fffffff)
>   {  _9DLL_Instance = NewDouble( (double)(unsigned long) hDLL ); Ref(hDLL);}

Matt, the Ref(hDLL) should be deleted. 
Ref should not be applied to a general 32-bit integer,
just to a 32-bit Euphoria object (a 31-bit integer, or a pointer), 
and it isn't needed anyway because NewDouble will set 
the ref-count to 1, which should be fine.
(Ref will be a no-op on a 31-bit Euphoria integer, so it won't do
any damage in that very common case.)

Also, you should change 0x7fffffff to 0x3fffffff, though 
your way will work by luck in many cases.

Maybe you should check make_atom as well.
(This bit fiddling stuff is very tricky. I hope I'm right here!)

For those who like bit fiddling, here is a 
chart of Euphoria internal 32-bit codes taken
from execute.h in the source:

  unused  : 011xxxxx xxxxxxxx xxxxxxxx xxxxxxxx
  unused  : 010xxxxx xxxxxxxx xxxxxxxx xxxxxxxx

  TOO_BIG:  01000000 00000000 00000000 00000000   (just too big for INT)

 +ATOM-INT: 001vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)
 +ATOM-INT: 000vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)
 -ATOM-INT: 111vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)
 -ATOM-INT: 110vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)

  NO VALUE: 10111111 11111111 11111111 11111111   (undefined object)

  ATOM-DBL: 101ppppp pppppppp pppppppp pppppppp   (29-bit pointer)

  SEQUENCE: 100ppppp pppppppp pppppppp pppppppp   (29-bit pointer)

8-byte alignment is always ensured when allocating 
sequence and double blocks, so the lower 3 bits of the address
are redundant, i.e only 29 bits are stored.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

30. Re: Where is my DLL?

Robert Craig wrote:
> 
> Matt Lewis wrote:
> > 
> > Juergen Luethje wrote:
> > > 
> > > Sorry, I don't want to bother anyone.
> > 
> > It's no bother.  If we didn't want to be bothered, we wouldn't read this
> > list. :)
> > 
> > > 
> > > Now I tested the following, which *seems* to work. I use this include
> > > file in my Eu program:
> > > 
> > > --------------------------[ dll_instance.e ]--------------------------
> > > }}}
<eucode>
> > > integer DLL_Instance_Hi, DLL_Instance_Lo
> > > -- DLL_Instance_Hi = 0           -- Initialize the variables only when
> > > -- DLL_Instance_Lo = 0           -- testing the program with the
> > >                                  -- interpreter, *not* when compiling
> > >                                  -- to a DLL!
> > > global function dll_instance()
> > >    return DLL_Instance_Hi*#10000 + DLL_Instance_Lo
> > > end function
> > > </eucode>
{{{

> > > ----------------------------------------------------------------------
> > > 
> > > 
> > > After translating the program for Borland, in "main_.c" I added two
> > > lines to DllMain(), so that it looks like this:
> > > 
> > > int __declspec (dllexport) __stdcall DllMain(int hDLL, int Reason, void
> > > *Reserved)
> > > {
> > >     _9DLL_Instance_Hi = (hDLL >> 16) & 0xFFFF;    // line added manually
> > >     _9DLL_Instance_Lo = hDLL & 0xFFFF;            // line added manually
> > >     if (Reason == 1)
> > >         EuInit();
> > >     return 1;
> > > }
> > > 
> > > Could one of our experts please tell me whether this can be considered
> > > safe?
> 
> Juergen, your multiplication code looks correct.
> 
> > That should work, since you're guaranteed to have a valid 31-bit integer.
> > You could alternatively do this (which is what make_atom does):
> > 
> > if( (unsigned)hDLL > (unsigned)0x7fffffff)
> >   {  _9DLL_Instance = NewDouble( (double)(unsigned long) hDLL ); Ref(hDLL);}
> 
> Matt, the Ref(hDLL) should be deleted. 
> Ref should not be applied to a general 32-bit integer,
> just to a 32-bit Euphoria object (a 31-bit integer, or a pointer), 
> and it isn't needed anyway because NewDouble will set 
> the ref-count to 1, which should be fine.
> (Ref will be a no-op on a 31-bit Euphoria integer, so it won't do
> any damage in that very common case.)
> 
> Also, you should change 0x7fffffff to 0x3fffffff, though 
> your way will work by luck in many cases.
> 
> Maybe you should check make_atom as well.
> (This bit fiddling stuff is very tricky. I hope I'm right here!)
> 
> For those who like bit fiddling, here is a 
> chart of Euphoria internal 32-bit codes taken
> from execute.h in the source:
> 
>   unused  : 011xxxxx xxxxxxxx xxxxxxxx xxxxxxxx
>   unused  : 010xxxxx xxxxxxxx xxxxxxxx xxxxxxxx
> 
>   TOO_BIG:  01000000 00000000 00000000 00000000   (just too big for INT)
> 
>  +ATOM-INT: 001vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)
>  +ATOM-INT: 000vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)
>  -ATOM-INT: 111vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)
>  -ATOM-INT: 110vvvvv vvvvvvvv vvvvvvvv vvvvvvvv   (31-bit integer value)
> 
>   NO VALUE: 10111111 11111111 11111111 11111111   (undefined object)
> 
>   ATOM-DBL: 101ppppp pppppppp pppppppp pppppppp   (29-bit pointer)
> 
>   SEQUENCE: 100ppppp pppppppp pppppppp pppppppp   (29-bit pointer)
> 
> 8-byte alignment is always ensured when allocating 
> sequence and double blocks, so the lower 3 bits of the address
> are redundant, i.e only 29 bits are stored.
> 
> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    <a href="http://www.RapidEuphoria.com">http://www.RapidEuphoria.com</a>
> 

So Rob when you implement dll_instance() in the next release, will it just be a
Windows only routine like instance()?, or would it work for Linux/FreeBSD shared
objects too?


Regards,
Vincent

new topic     » goto parent     » topic index » view message » categorize

31. Re: Where is my DLL?

Robert Craig wrote:
> 
> Matt Lewis wrote:
> > 
> > 
> > if( (unsigned)hDLL > (unsigned)0x7fffffff)
> >   {  _9DLL_Instance = NewDouble( (double)(unsigned long) hDLL ); Ref(hDLL);}
> 
> Matt, the Ref(hDLL) should be deleted. 
> Ref should not be applied to a general 32-bit integer,
> just to a 32-bit Euphoria object (a 31-bit integer, or a pointer), 
> and it isn't needed anyway because NewDouble will set 
> the ref-count to 1, which should be fine.
> (Ref will be a no-op on a 31-bit Euphoria integer, so it won't do
> any damage in that very common case.)

Yes, I cut and pasted and put hDLL where I meant to put _9DLL_Instance.
I didn't know that NewDouble() Ref'd, though.  I think I was basing stuff
on examples of translated code.

> Also, you should change 0x7fffffff to 0x3fffffff, though 
> your way will work by luck in many cases.
> 
> Maybe you should check make_atom as well.
> (This bit fiddling stuff is very tricky. I hope I'm right here!)

Oops, you're right, of course.  I'll fix that up and re-submit.

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

32. Re: Where is my DLL?

Vincent wrote:
> So Rob when you implement dll_instance() in the next release, will it just be
> a Windows only routine like instance()?, or would it work for Linux/FreeBSD
> shared objects too?

Just for Windows.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

33. Re: Where is my DLL?

Robert Craig wrote:

<snip>

> Juergen, your multiplication code looks correct.

<snip>

Thanks for checking it.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu