|
You have to specify the calling convention of the exported function because the default is different in managed and native compilation.
You could declare it as __stdcall.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
would you please elaborate a little bit more or send me an article with examples?
Thanks a lot
|
|
|
|
|
The function must be declared as -
extern "C" int __stdcall foo();
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
Here[^] is a great article about calling conventions. It will help you to understand the concept.
|
|
|
|
|
Hi,
I want to know the side effects if I don't save the value returned from a function call.
ex:
int foo()
{
return (10);
}
main()
{
foo();
}
Doubts:
1. Does this type of code may cause some warnings or other issues?
2. Is it an optimized approach or do I need to save the value returned by foo()?
Thanks for ur help.
Akash
|
|
|
|
|
Ideally, you should take the returned value because there is some reason for the returning it.
Could be an error code that most people don't check.
As for optimization, you will have one less instruction if you don't take the return value.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
yaa, true...
But if I've already checked for error conditions and all. does it matter...
|
|
|
|
|
It really doesn't matter.
For example, I didn't know printf returned any value at all for a long time.
I believe its return value is not checked 99% of the times.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
akashag wrote: 1. Does this type of code may cause some warnings or other issues?
Compile it and see...neither gcc nor VC++ seem to give any warnings.
akashag wrote: 2. Is it an optimized approach or do I need to save the value returned by foo()?
You don't need to save the return value...but you then have to ask yourself - why am I calling the function? Doers it have other, non-visible side-effects? Obviously, this simple case doesn't, but many functions do effect some form of global data, while class methods can obviously update object instance data.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I can discover from the trusty old DOS functions on which logical drive I currently am say, drive 'C:', or drive 2. logical drive typically represents a volume on a physical drive, say '\\\\.\\PhysicalDrive0' What API's are there to translate from a locical drive identifier to the physical drive which contains the volume.
regards
|
|
|
|
|
You could use the IOCTL_STORAGE_GET_DEVICE_NUMBER[^] control code to obtain the physical drive and volume number.
For example:
#include <Winioctl.h>
VOID LogicalToPhysical(TCHAR *szDrive)
{
CString szPhysical;
HANDLE h = CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(INVALID_HANDLE_VALUE != h)
{
STORAGE_DEVICE_NUMBER sd;
DWORD dwRet;
if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sd, sizeof(STORAGE_DEVICE_NUMBER), &dwRet, NULL))
{
szPhysical.Format(_T("\\\\.\\PhysicalDrive%d"), sd.DeviceNumber);
}
CloseHandle(h);
}
}
LogicalToPhysical(_T("\\\\.\\\\C:"));
Note that this control code will fail to return correct information for mirrored and striped volumes. A more complete solution for these types of drives would be the IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS[^] control code which will return an array of partitions for the drive.
Best Wishes,
-David Delaune
|
|
|
|
|
Thanks David,
Exactly the hint I Needed.
Only One Snag, Cannot find the (hex)Value of IOCTL_STORAGE_GET_DEVICE_NUMBER. Could you let me know?
Thanks and Regards,
Bram van Kampen
modified on Tuesday, August 11, 2009 5:17 PM
|
|
|
|
|
Bram van Kampen wrote: Cannot find the (hex)Value of IOCTL_STORAGE_GET_DEVICE_NUMBER.
Interesting. They are declared in the Winioctl.h header file.
Some questions:
1.) What development environment are you using?
2.) What version of the Platform/Windows SDK are you using if any?
You can probably get away with dropping these declarations somewhere:
#define FILE_ANY_ACCESS 0
#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
#define METHOD_BUFFERED 0
#define METHOD_IN_DIRECT 1
#define METHOD_OUT_DIRECT 2
#define METHOD_NEITHER 3
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
#define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _STORAGE_DEVICE_NUMBER {
DEVICE_TYPE DeviceType;
DWORD DeviceNumber;
DWORD PartitionNumber;
} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
You should really correctly setup your development environment rather than dropping the above declarations into your project. Are you using VC6 or something?
Best Wishes,
-David Delaune
|
|
|
|
|
|
Many thanks, that solved the problem. I had looked at DeviceIoControl() but my (outdated) Winioctl.h did not have is call param!
Regards
Andy
|
|
|
|
|
Hey Andy,
Great to hear that it solved your problem. Yeah... I am also using old Microsoft compilers such as VC6/2005 and I have them all installed side-by-side. You should probably keep an updated 'Platform SDK'... which I believe has been renamed to 'Windows SDK'.
Somebody should probably post an article or tip that shows which SDK updates are compatible with each compiler... I am somewhat surprised that Microsoft does not have such a document. You cannot use many of the more recent 'Microsoft SDK' packages with older MS compilers. I have actually been successful with modifying some of the later SDK headers to make it work with older compilers... but that's probably not encouraged or supported.
Anyway, good luck with your project. (Why are you working the day after Christmas?)
Best Wishes,
-David Delaune
|
|
|
|
|
Hi David
I was a bit suprised to receive your last mail. Most people don't bother to 'follow up'.
Yes, all my stuff belongs in a museum. But, funds don't permit upgrades yet. I'm now in my 60's after over forty years in computing, single, live alone - hence working over the holidays.
A couple of questions. In your solution you gave this format "\\\\.\\\\%c:". I assume this to be for extended filepath string length support. But the documenation with my old compiler has it as "\\\\.\\"
Is this the norm for extended length support? Users are bound to come up super long path names.
Also, in my application I also access network drives. Does the "\\\\pc name\\drive name\\" give this extended length support?
Regards
Andy Belton
|
|
|
|
|
Hey Andy,
Andy Belton wrote: A couple of questions. In your solution you gave this format "\\\\.\\\\%c:". I assume this to be for extended filepath string length support. But the documenation with my old compiler has it as "\\\\.\\"
Actually the documentation to your old compiler is correct... for opening the device namespace you need to prepend "\\.\" which as you know escaped looks like "\\\\.\\"
I have no idea why my old code snippit from 2009 contains an extra backslash. I write alot of these code snippits impromptu... so some of them may contain typos or minor flaws. I can tell by looking at the above code snippit that I wrote it on the spot... because it doesn't return a value... or modify any variables being passed into the function. It is just enough to illustrate the idea and help the developer move forward.
Andy Belton wrote: Is this the norm for extended length support? Users are bound to come up super long path names.
I believe that you are referring to the Unicode version of the CreateFile Function[^]... you would need to prepend a L"\\?\" which escaped for c++ looks like L"\\\\?\\"
Andy Belton wrote: Also, in my application I also access network drives. Does the "\\\\pc name\\drive name\\" give this extended length support?
Yes, you can access files over the network with a path greater than 260 characters however you will need to use the Unicode version of CreateFile function[^]
Best Wishes,
-David Delaune
|
|
|
|
|
Hi David
Sorry to bug you again.
My application was finished and put out for field trials. Yup - it hit a couple of problems (well quite a few actually). Most were trivial to solve. However, I am stuck with two, both related (one directly the other indirectly) to my original question.
To help understand the setup, the application is XP platorm based and used primarily at the client office. Howeverm the application also needs to be used in the field (litteraly). So the client wanted the facility to copy work data files on to a second drive that could then be sent out to 'engineers' working in the field who could then interogate them on whatever they have there.
The reason for getting the Physocal drive info wsa to ensure that the files were not written to the same physical drive. After writing, the target drive is removed and sent out. (The drive can be internal or external). (That is about the limit as to what I can disclose for security reasons).
In my code, I used your solution to obtain the physical drive information. I compare the DriveNumber and PartionNumber numbers to enure they are different drives. This is fine. But I think that I should also be check which controller is being used as I could be blocking a drive that is actually on a different controller.
So, Question 1 - How do I determine the drive controller? I have spent some time searching both MSDN and CodeProject and have not found an obvious answer. I think what I need to find are the four parameters as used in boot.ini to select the boot operating system.
Now for the indirectly related problem. In practice, the client is using whatever hard drive comes to them from another source. Normally this drive is NTFS formated but some times it is FAT formated. I have no control over this and neither does the client. Out in the field I am using the file modified date from GetFileInformationEx(). This is because all files are loaded to be shipped out but, only those that have a later date to those exisiting in the field are used. However, we are getting problems with file dates.
It appears that if you copy a file from NTFS to a FAT file system the date can change. The FAT system does not store the milliseconds, instead the time is rounded up. I could deal with this if it were consistant but, I have seen a direct file copy between two drives and the times have been different by as much as five minutes! In one instance, I actually witnessed the file date being two minutes ahead of the current time! Any thoughts on this one? Please?
So, Question 2 - how can I ensure a consistant date record on a FAT drive? I do detect the drive file system and display this to the user.
Best regards
Andy Belton
|
|
|
|
|
I'm using the stringstream and the operator << receiving data from a input string, like this:
stringstream ss;
ss.clear();
ss.str("");
ss << inputString;
-------------
string outputString = ss.str();
The string is big and contains white spaces, etc.
Sometimes the "outputString" string reflects the entire inputString, sometimes it's truncated until it reaches a white space...in the same project.
Why it happens ? Is there any way\flag to reset any iostream data processing ?
Thanks for any help.
|
|
|
|
|
- Can you give an example of a failing input string?
- You don't need these lines - the stringstream will be empty on cosntruction:
ss.clear();
ss.str(""); - Does using an ostringstream help (I doubt it)?
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Problem solved using the .str() method, I finally could figure out a way to specialize my templates and use the unformated version with strings.
Anyway, thanks a lot for your valuable tips.
|
|
|
|
|
Hey, I'm doing sockets programming. Pretty much new to it.
The application is a Windows Service, in its ServiceMain() function I call CAsyncSocket's Listen() method, to listen for client connections. But after it starts listening for connections, it'll return and the ServiceMain() function will return and the service is stopped.
What I want to do with this is that, wait until a specific event occurs say WM_QUIT, till than listen for connections. How to do it?
void CNTService::ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
m_Server.StartListening();
}
I'm okay with mixing Win32 and MFC, so if it can be done in Win32 please do tell me too
|
|
|
|
|
Ahmed Manzoor wrote: What I want to do with this is that, wait until a specific event occurs say WM_QUIT
Does the service have a window (and associated window queue) on which to listen for window messages? Doubt it...
Instead, use a Win32 IPC event object[^] with a name specific to your service (hint: use an ASCII representation of a UUID to get a unique name) and wait on that with WaitForSingleObject[^].
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
But, won't that block the thread and everything will stop!
|
|
|
|