A friend of me has bought a piece of data-acquisition hardware that connects to a PC through a USB port. He is not an experienced programmer, so I offered to help him to get it running. But I run into problems that are beyond me as well.
The hardwre comes with a disk that contains drivers in a DLL file. A manual gives the name of the routine, and there are several examples included. But they are all for compilers I do not have (and neither does my friend): VC6, VC2005, VB, Delphi.
Now I thought that DLLs were machine-language programs with a standard interface, so that any language that supports DLLs can use the same DLLs. Before this I used a DLL exacty once in my life. It seemed simple enough: I loaded the DLL by calling LoadLibrary(), and then I requested a pointer to the routine I want to call with GetProcAddress().
When I try the same now, however, I can load the DLL (the handle returned by LoadLibrary() is non-NULL), but none of the names of the driver routines described in the manual can be found by GetProcAddr(). (It always returns 0).
Now there is a .lib file with the same name as the DLL. Some texts I googled up seem to suggest that the address information on the entry points might be in there. (I could not fully understand what they were saying.) But I am not sure how to use this .lib file. I am using gcc. A .lib sounds like it is a static linking library. But the object file format of gcc and VC2005 is not compatible, is it? So I cannot simply link the .lib file to the rest of my sources.
I am not even sure how VC2005 uses the .lib file. There is no make file, so I guess this information is hidden in the .vcproj file. Altough this is a text file, I have no idea what all the stuff in there means.
Can anyone help me, by explaining me how I should use the .lib file with gcc, or how I can otherwise find out the addresses of the driver routines in the DLL?
Question on DLL use (non-chess)
Moderators: hgm, Rebel, chrisw
-
- Posts: 27808
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
-
- Posts: 12541
- Joined: Wed Mar 08, 2006 8:57 pm
- Location: Redmond, WA USA
Re: Question on DLL use (non-chess)
If you link against the library, that will give you the entry points.
You should also have a header file (.h).
If dynamic loading is not working, then something is wrong, because that method should work also.
The first thing to do is get the module handle something like this:
You should also have a header file (.h).
If dynamic loading is not working, then something is wrong, because that method should work also.
The first thing to do is get the module handle something like this:
Code: Select all
#ifdef WIN32
hOracleDll = GetModuleHandle("OCI.DLL");
#else
#if defined(HPUX) && ! defined(ITANIUM)
hOracleDll = LoadLibrary("libclntsh.sl");
#else
hOracleDll = LoadLibrary("libclntsh.so");
#endif
#endif
[code]
and then collect the proc addresses that you need something like this:
[code]
fnOCIEnvCreate = (pfnOCIEnvCreate)GetProcAddress(hOracleDll, "OCIEnvCreate");
fnOCITerminate = (pfnOCITerminate)GetProcAddress(hOracleDll, "OCITerminate");
[/code]
where the function pointers have the correct signature for the function type. You get the signature for the function pointers by examination of the supplied header file.
-
- Posts: 27808
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Question on DLL use (non-chess)
With code similar to what you wrote above, without linking against the .lib, I crash because of calling a NULL pointer. (GetProcAddress returns 0.)
Can GCC link against a library that is meant for VC2005?
If I fail to link to a library that I need, I would have expected to get 'undefined references' messages during the linking. If I have no undefined references from the exlicitly mentioned files, why would the linker include any modules from the library?
Can GCC link against a library that is meant for VC2005?
If I fail to link to a library that I need, I would have expected to get 'undefined references' messages during the linking. If I have no undefined references from the exlicitly mentioned files, why would the linker include any modules from the library?
-
- Posts: 12541
- Joined: Wed Mar 08, 2006 8:57 pm
- Location: Redmond, WA USA
Re: Question on DLL use (non-chess)
No problem if it is Mingw GCC.hgm wrote:With code similar to what you wrote above, without linking against the .lib, I crash because of calling a NULL pointer. (GetProcAddress returns 0.)
Can GCC link against a library that is meant for VC2005?
I have no idea what will happen with Cygwin.
If I fail to link to a library that I need, I would have expected to get 'undefined references' messages during the linking. If I have no undefined references from the exlicitly mentioned files, why would the linker include any modules from the library?
-
- Posts: 12541
- Joined: Wed Mar 08, 2006 8:57 pm
- Location: Redmond, WA USA
Re: Question on DLL use (non-chess)
When you dynamically load, you have to check the returns yourself, and there is no such thing as an unresolved external if you dynamically load the function pointer.Dann Corbit wrote:No problem if it is Mingw GCC.hgm wrote:With code similar to what you wrote above, without linking against the .lib, I crash because of calling a NULL pointer. (GetProcAddress returns 0.)
Can GCC link against a library that is meant for VC2005?
I have no idea what will happen with Cygwin.
If I fail to link to a library that I need, I would have expected to get 'undefined references' messages during the linking. If I have no undefined references from the exlicitly mentioned files, why would the linker include any modules from the library?
-
- Posts: 388
- Joined: Wed Mar 08, 2006 10:08 pm
Re: Question on DLL use (non-chess)
My suggestion is for you to search the web for "DLL export viewer". Look for utilities that will allow you to view the functions (names) that are exported by a DLL. Verify this against the function name that you are passing to GetProcAddress().hgm wrote:A friend of me has bought a piece of data-acquisition hardware that connects to a PC through a USB port. He is not an experienced programmer, so I offered to help him to get it running. But I run into problems that are beyond me as well.
The hardwre comes with a disk that contains drivers in a DLL file. A manual gives the name of the routine, and there are several examples included. But they are all for compilers I do not have (and neither does my friend): VC6, VC2005, VB, Delphi.
Now I thought that DLLs were machine-language programs with a standard interface, so that any language that supports DLLs can use the same DLLs. Before this I used a DLL exacty once in my life. It seemed simple enough: I loaded the DLL by calling LoadLibrary(), and then I requested a pointer to the routine I want to call with GetProcAddress().
When I try the same now, however, I can load the DLL (the handle returned by LoadLibrary() is non-NULL), but none of the names of the driver routines described in the manual can be found by GetProcAddr(). (It always returns 0).
Now there is a .lib file with the same name as the DLL. Some texts I googled up seem to suggest that the address information on the entry points might be in there. (I could not fully understand what they were saying.) But I am not sure how to use this .lib file. I am using gcc. A .lib sounds like it is a static linking library. But the object file format of gcc and VC2005 is not compatible, is it? So I cannot simply link the .lib file to the rest of my sources.
I am not even sure how VC2005 uses the .lib file. There is no make file, so I guess this information is hidden in the .vcproj file. Altough this is a text file, I have no idea what all the stuff in there means.
Can anyone help me, by explaining me how I should use the .lib file with gcc, or how I can otherwise find out the addresses of the driver routines in the DLL?
-
- Posts: 27808
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Question on DLL use (non-chess)
OK, this DLL export viewer was a great idea. Many thanks for that. The problem turned out to be that names which in the manual occurred as xxx, would have entry points in the DLL under the name _xxx@4. I had been smart enough to try the underscore, but not the suffix. This apparently indicates the number of bytes in the arguments.
Now I run into the following problem, however:
The routines in the DLL seem to all pop their arguments from the machine stack before returning. My compiler (gcc) expects routines to leave the stack untouched. This of course leads to a quick crash fter a certan number of calls to the DLL.
Is this incompatible calling sequence a consequence of a wrong declaration of the DLL routines? I am using
const void *(__cdecl *RoutineName)()
now. Is there another declaration possible that would make gcc aware that this is a routine that messes up the stack, so that it adapts its callng code to it?
Now I run into the following problem, however:
The routines in the DLL seem to all pop their arguments from the machine stack before returning. My compiler (gcc) expects routines to leave the stack untouched. This of course leads to a quick crash fter a certan number of calls to the DLL.
Is this incompatible calling sequence a consequence of a wrong declaration of the DLL routines? I am using
const void *(__cdecl *RoutineName)()
now. Is there another declaration possible that would make gcc aware that this is a routine that messes up the stack, so that it adapts its callng code to it?
-
- Posts: 1922
- Joined: Thu Mar 09, 2006 12:51 am
- Location: Earth
Re: Question on DLL use (non-chess)
Are you sure you don't have it backwards? According to this: http://msdn.microsoft.com/en-us/library ... S.71).aspx
__cdecl means the function is in charge of cleaning up the stack, and __stdcall leaves it mangled. I would try __stdcall though.
__cdecl means the function is in charge of cleaning up the stack, and __stdcall leaves it mangled. I would try __stdcall though.
-
- Posts: 88
- Joined: Wed Mar 25, 2009 12:49 pm
Re: Question on DLL use (non-chess)
__stdcall._xxx@4
-
- Posts: 27808
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Question on DLL use (non-chess)
You re right. That was the problem, and the solution I was looking for. I did not have anything backwards or forwards, as I did not know anything at all. I just adapted the only thing that I had working, without knowing why. Which happened to use a DLL with another calling convntion (where I was not even aware that multiple calling conventions existed).
But everything starts to become clear now!
Thanks for the advice, everyone!
But everything starts to become clear now!
Thanks for the advice, everyone!