|
dean9359 wrote: (TryPIDs2 error LNK2001: unresolved external symbol "int __stdcall EnumProcesses(unsigned long *,unsigned long,unsigned long *)" (?EnumProcesses@@$$J212YGHPAKK0@Z)
Dynamically load function from the dll, i.e. by using LoadLibrary and GetProcAddress!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You/codeProject$$>
|
|
|
|
|
Thanks.
LoadLibrary and GetProcAddress are the answer!
There was an interesting sticking point regarding the use of FARPROC (A compiler error - C2564) that is addressed in a microsoft KB item: http://support.microsoft.com/kb/117428[^]
modified on Friday, March 28, 2008 4:14 PM
|
|
|
|
|
dean9359 wrote: LoadLibrary and GetProcAddress are the answer!
My pleasure
|
|
|
|
|
Hi,
I created a DLL that exports an API for a GUI to use.
The GUI call the API and when the function returns, it expects to have some value set in the memory sent to the API, so far so good.
The DLL itself implements the API by sending some information over CAsyncSocket.
Here is my problem,
When I send the data from the DLL to the client, I basically need to block until the client returns my packet back. I do that using a HANDLE set up as an event.
When the client would return my call the OnReceive of the socket would get called and then I would set the event.
However.....
It seems like the blocking (WaitForSingleObject (event, INFINITE)) seems to prevent the listening socket from receiving the reply. Once the blocking is commented out, I get the reply from the client. The problem is that if I remove the blocking my API returns right away and the the GUI has nothing in the buffer
I know this can be solved with some threading and callbacks and so on. BUT... the listen socket should be a thread of it's own and not be affected by the infinite wait of WaitForSingleObject .
what am I missing ?
|
|
|
|
|
Shay Harel wrote: what am I missing ?
Almost everything. Your most direct solution would be to use blocking socket calls. Then later should you choose to migrate to a multi-threading solution to keep the UI responsive during socket I/O, I strongly suggest you do a lot of studying and research projects for multi-threading. You are a long way from grasping these concepts well enough to use it in a production application.
I recommend Jeffery Richter and his Advanced Windows book for a study resource on threading.
led mike
|
|
|
|
|
Wow,
All I asked for was a technical solution
I have done many multithreading in my life, don't loose sleep over it.
I was under the impression the listening socket would not be affected from the blocking, that's all.
As for the expected blocking of the GUI, I am aware of that, but my traffic is always quick enough for the client to respond quick enough not to notiec the GUI bloking.
Also, this is just a prototype at this stage so I don't mind the GUI blokc. In the future, the code that would use the DLL would have a thread of it's own. But if the listening socket would be blocked by this thread I am at the same state.
Sync sockets should seems like the only solution but I wanted to avoid it...
|
|
|
|
|
Shay Harel wrote: I have done many multithreading in my life, don't loose sleep over it.
Ok, good luck
led mike
|
|
|
|
|
The problem is you're using CAsyncSocket, which by default needs the message pump
working to dispatch asynchronous socket notifications.
I would recommend (for your prototype which doesn't use multiple threads)) using sockets
directly and using WSAEventSelect() so you can get notifications through an event instead
of a window message.
Either that, or you have to modify the way you wait.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
"The problem is you're using CAsyncSocket, which by default needs the message pump
working to dispatch asynchronous socket notifications."
This is exactly the root cause of the problem I guess. I did not know the Async socket rely on the message pump, I was sure it's a thread of it's own.
Looks like I'll have some threads going...
Thanks !
|
|
|
|
|
Shay Harel wrote: I did not know the Async socket rely on the message pump
It does by default. You can, however, override everything you need to make it use events
instead of window messages. You don't get the virtual OnConnect(), OnReceive(), etc calls,
however, since you'd have to provide your own thread. At some point it ends up being easier to use
Winsock APIs directly IMO
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi, it looks like you want to turn an asynchronous process into a synchronous process. I wonder why you decided to use CAsyncSocket in the beginning but I could suggest two designs:
If you can influence the API then I would change it, instead of calling blocking the API call could accept a window message (or another type of notification) and when the request has completed it will signal that the data is available.
If you can't change the API or it would be too costly then there is my sugestion number two which is to wrap this mechanism internally into a worker thread... or simply to implement it with blocking sockets.
Since you mentioned your application is a GUI and I assume it is event driven, perhaps the first alternative is the best.
Hope it helps!
Moak
|
|
|
|
|
As Mark said, blocking the message pump seems to be problem. Try using MsgWaitForMultipleObjects instead of WaitForMultipleObjects .
|
|
|
|
|
Hi,
Does anyone have any c++ code that will convert a web page into an image file, even if all of the page is not displayed on the screen.
|
|
|
|
|
|
Hi,
I have been trying to read a file in a program from a USB flash drive. I know that windows allows me to use the device as a drive and I can read the file like reading from any other drive. But the problem is the flash drive will be connected to different PC and the drive name could change. So I cannot use the drive name.
I am using SetupDI API to get the interface and I am also able to get the handle using CreateFile(). But I do not know how to read a particular file.
Can anyone help me here? Also is there any tutorial that will help me to work with USB drives in WinXP environment?
|
|
|
|
|
koumodaki wrote: But I do not know how to read a particular file.
Do you know the file's name?
"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
|
|
|
|
|
Yes I do know the file's name.
|
|
|
|
|
So then can't you call ReadFile() ?
"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
|
|
|
|
|
I have a file context.cfg which needs to be read form the flash drive. How do I specify in the ReadFile() parameters that I need to read this particular file. From what I know, I can pass the handle I obtain while opening the usb flash drive from CreateFile() to this function. How do I get hold of the file inside the flash drive
|
|
|
|
|
What does your call to CreateFile() look like?
"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
|
|
|
|
|
I enumarate the USB device first and get the interface using SetupDiGetDeviceInterfaceDetail(). The name is stored in a vector Devices. Then I use the following call:
HANDLE hUsbDevice = CreateFile(Devices[0].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
|
|
|
So what happens if you use:
string str = Devices[0] + "\\context.cfg";
HANDLE hUsbDevice = CreateFile(str.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
"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
|
|
|
|
|
Havent tried that. Will check it out
|
|
|
|
|
I tried the method you suggested. I did not work. The code snippet is
std::string path = Devices[0] + "\\context.cfg";
HANDLE hUsbDevice = CreateFile(Devices[0].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hUsbDevice == INVALID_HANDLE_VALUE)
return 1;
char data[MAX_PATH];
DWORD nNumberOfBytesToRead = MAX_PATH;
DWORD lpNumberOfBytesRead = 0;
if(!ReadFile(hUsbDevice,(void*)data, nNumberOfBytesToRead, &lpNumberOfBytesRead,NULL))
{
int err = GetLastError();
return 0;
}
GetLastError() returns ERROR_INVALID_PARAMETER
|
|
|
|
|
koumodaki wrote: I tried the method you suggested.
But the code snippet you posted does not reflect such. You are not using path .
I like Judy's suggestion better.
"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
|
|
|
|