|
tiwal wrote: included the dll code in a .cpp file, as I did with the calling code , so I think there
should be no name-mangling problems .
I think that you'll get no name-mangling problems only with implicit linking, you probably need to surroud with extern "C" block your functions
(see http://msdn2.microsoft.com/en-us/library/ms682507.aspx[^]).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
I've tried this option, but it does not work.
All I know is that when the C++ compiler compiles a function in a C++ file, it mangles its name, quite differently from the compiling of a C file, which doesn't do this. So if you try to export a symbol from a C file which is compled by the C++ compiler , and try to use it in a C++ file , you must tell the C++ not to mangle the call in the C++ file, and you do this by using the extern "C"
directive.
Here , I am using .cpp files in both the dll and the calling program, so there shouldn't be any of these problems ... and in effect using extern "C" , as I told you, doesn't change anything .....
|
|
|
|
|
tiwal wrote: Here , I am using .cpp files in both the dll and the calling program, so there shouldn't be any of these problems
This is wrong, because GetProcAddress does not expect a C++ mangled function.
I made a little test:
DLL header
...
#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
DLLTEST_API int fnDLLMul(int i, int j);
#ifdef __cplusplus
};
#endif
DLL source code
...
DLLTEST_API int fnDLLMul(int i, int j)
{
return i*j;
}
Client source code
#include "stdafx.h"
#include <windows.h>
typedef int (*LPFUNMUL)(int, int);
int _tmain(int argc, _TCHAR* argv[])
{
int i=5;
int j=6;
HMODULE hLib = LoadLibrary(_T("..\\..\\DLLTest\\debug\\DllTest.Dll"));
LPFUNMUL fnMul =(LPFUNMUL) GetProcAddress(hLib, "fnDLLMul");
DWORD dwErr= GetLastError();
_tprintf(_T("%d * %d = %d"), i, j, fnMul(i,j));
getchar();
}
And it works fine (error checking left to the reader).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
What you say is interesting : maybe GetProcAddress () has to be handled differently in a C++ environment.
By the way , I adapted my (very simple) code to your example , but it didn't work either.
I mean, I included a header file with __declspec(dllimport) and extern "C" directives in the calling code, but the error code is always the same (127).
I shouldn't need to use a header file and a dllimport directive in my case, since I'm linking my dll explicitly, and as far as I know this is only needed when you do it implicitly (that is , with a .lib for the export of symbols).
As the dll is loaded by the LoadLibrary, the system should look into its export table and check the symbol you specified in GetProcAddress () against those in that table : once it finds it, it should return the RVA associated with that symbol , so why use a header file and a dllimport statement ?
The fact instead, that GetProcAddress () couldn't be able to handle mangled names , is interesting : even if I really don't know how to work around it ....
|
|
|
|
|
tiwal wrote: By the way , I adapted my (very simple) code to your example , but it didn't work either.
I mean, I included a header file with __declspec(dllimport) and extern "C" directives in the calling code, but the error code is always the same (127).
You haven't to do this. I haven't done it. You need to use the extern "C" block when you compile your DLL using C++ , because you need to export C interface (the one recognized by GetProcAddress ), see (again) MSDN http://msdn2.microsoft.com/en-us/library/ms682507.aspx[^].
tiwal wrote: I shouldn't need to use a header file and a dllimport directive in my case, since I'm linking my dll explicitly, and as far as I know this is only needed when you do it implicitly (that is , with a .lib for the export of symbols).
The above is true. in fact I didn't use neither header file nor dllimport directive in my example.
tiwal wrote: he fact instead, that GetProcAddress () couldn't be able to handle mangled names , is interesting : even if I really don't know how to work around it ....
Simply GetProcAddress is designed to handle the C programming interface (WIN32 is a C API , after all), moreover, AFAIK, there is no unique standard (among compiler productors) on function name mangling.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
I've seen that you're using a dll header , which includes the exported function prototype ....
using extern "C" right before the function definition is just the same , isn't it ?
Anyway, the fact that there's no unique standard on function name mangling scares me ....
What does it mean ? that you can't use a dll in a program that's not compiled with the same environment ?
|
|
|
|
|
tiwal wrote: I've seen that you're using a dll header , which includes the exported function prototype ....
The DLL header has two purposes (a macro (un)definition makes the trick):
(1) Correctly declare the functions for exportation when compiling the DLL itself.
(2) Correctly declare the function for importation whenever you compile an application that links at load time the DLL (i.e. implicit link, via .lib file).
Since you application uses run-time (explicit) DLL link, then the header is not needed.
tiwal wrote: using extern "C" right before the function definition is just the same , isn't it ?
Using the extern "C" block when compiling (with C++) the DLL makes it exporting a C-like interface, the same kind exported by the Win32 API; run time linking such kind of interface is simpler.
tiwal wrote: Anyway, the fact that there's no unique standard on function name mangling scares me ....
What does it mean ? that you can't use a dll in a program that's not compiled with the same environment ?
Yes, there are compatibility issues, see for instance
http://blogs.msdn.com/oldnewthing/archive/2004/01/12/57833.aspx[^]
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
tiwal wrote: I'm linking the dll "explicitly", that is , I'm using the LoadLibrary() + GetProcAddress()
What is the reason you are not using the lib file for linking?
|
|
|
|
|
I could have done it implicitly, but I just want to learn how to do it explicitly, since MSDN says it can be done ...
After all ,there may be a reason for linking explicitly (that is not aborting the program in case of failure loading the dll).
|
|
|
|
|
Hmm, I'd start by looking at the exporting Dll with some tools like Depends.exe for example that can examine the headers for exports. PEViewer is knocking around which can dig really deep if you need to. If it's not a calling convention issue it could be name mangling, some calling conventions add all sorts of goo to export names and it's different on different Compilers. Also make sure that all the types in the function interfaces are present and identical on both sides of the call otherwise nasty things will happen to your stack. Ouch!
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Dependency Walker tells me that I actually export two symbols : Function_ADD@12 and Function_SUB@12 ...
In my DLL's code the functions are Function_ADD and Function_SUB , so it appears that mangling has been done ( ) ...
More , the Dependency Walker states that the symbols are exported , at least it seems , in an ordinal way :I see the "ordinal" field with the values "1" and "2" respectively for the two functions ...
But I'm not using a .def file ....
About the calling conventions, I tried to force the __stdcall both in the project and in the code , but nothing changed (I've read somewhere that you have to declare the function, and then call them. as __stdcall ) ....
Anyway I don't think there are stack problems since my calling program doesn't ever crash , it simply warns me that it didn't find the entry points : that's way I'm quite convinced that something goes wrong in the export....
As you suggested, I'll try to use PEWiever to see if i can understand something more ...
|
|
|
|
|
tiwal wrote: Dependency Walker tells me that I actually export two symbols : Function_ADD@12 and Function_SUB@12 ...
In my DLL's code the functions are Function_ADD and Function_SUB , so it appears that mangling has been done
The extern "C" block prevents the above.
I've built a little sample DLL exporting a single function (see my reply
http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=2376287[^]) and no-mangling appears in dependency walker.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Are you sure those two functions are actually being exported?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Well, all I can say is that Dependency Walker finds two exported symbols, just what I meant to do ...
but the way they are exported, is a totally different thing ... It seems they are exported in an ordinal way , when instead I wanted to use them explicitly (that is , without .lib reference)
|
|
|
|
|
Does the name in the export table exactly match the argument that you are passing to GetProcAddress()?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
no it doesn't...after all I expected (incorrectly) that the name to pass to GetProcAddress() would have been the same , be it a c function or a cpp function ....
As I pass a mangled name , it does work perfectly ....
|
|
|
|
|
First I must say Happy New Year however today is 3 january but did you get my mail?
|
|
|
|
|
Yes, I received your e-mail.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
|
In effect much of my coding is based on such articles , and of course on MSDN too ...
But seems like there's something at a lower level to be analized ....
|
|
|
|
|
Hello everyone,
I have several physical file and I want to use file map (MapViewOfFileEx) to map the file into memory to improve performance. Each file is about several hundred M bytes. All the memory mapped files are kept open during my application.
The mapping is successful, but the strange thing is,
1. the performance to access the files which are opened at first is very fast;
2. the performance to access the files which are opened later is slower and slower (the performance to access the 10th file is very bad).
Any ideas to improve performance?
thanks in advance,
George
|
|
|
|
|
Buy memory.
Probably memory is swapped again to disk.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
More RAM is the only true religion when it comes to this sort of performance. If you have plenty and aren't getting the performance anyway then try fiddling the size of something called Non-Paged Pool. This is memory that doesn't get swapped out, ever, so be careful. I've seen this trick used on a dedicated system to allow a 2GHz Pentium 4 to do 16 simultaneous audio transforms and recordings off a bunch of 100MB Ethernet cards while serving the audio over the Web. Is that my PCI bus I can smell burning
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
All,
I have a doubt whether two different threads can be working on a same socket descriptor(handle in windows terminology)?
Please go through the following scenario:
We have one device which supports TCP/IP:
1. Responds to the requests
2. Sends notifications, incase any events
Can I have two threads one for continuesly wait to receive the notifications & response and another for sending the requests to the panel?
Could someone please provide (link will suffice)a good design for this class.
Best Regards,
Pratap
|
|
|
|
|
Raj Prathap wrote: Can I have two threads one for continuesly wait to receive the notifications & response and another for sending the requests
You can read from the socket in one thread and write to the socket in a different thread. I think that is what you mean and Yes you can.
|
|
|
|
|