|
This question has been anwered with:
#include <cstring>
//...
strcpy( Date, holder );
|
|
|
|
|
This will only work if he is using a wide string, in which case it would be wcscpy because BSTR is a wide string.
To copy a BSTR into an ASCII string, you will need to convert the character set.
|
|
|
|
|
Disregarding the method of conversion, the assignment you used attempts to assigns an array of characters to single character: Date is defined as an array of ARR characters, and Date[cyc] denotes the character with the index cyc within that array.
What was your intention? I suspect that what you really wanted is to define Date as an array of strings rather than as an array of characters. In this case you should define Date as char* Date[ARR]; .
On a sidenote, what you are trying to achieve is like pouring milk into a crate for beer bottles: you can't just go ahead and assign the contents of one variable to another variable that is designed to hold something completely different - doing this will usually result in spilling the contents. Instead you have to use the proper function or method for transfering the contents of one variable into the other. Plus you might need to allocate proper containers first: so first thing, pick up an empty beer bottle, then pour the milk into it, and only then you can put that bottle into the crate.
With respect to these strings, the Date array corresponds to the crate for beer bottles. The beer bottles correspond to char-strings, and the milk corresponds to the contents of that _bstr_t. So what you have to do is:
- allocate an array of char, big enough to hold the _bstr_t
- call the appropriate method to convert a _bstr_t into a char*, and then
- put it into the Date array.
|
|
|
|
|
Hello
I have some trouble interpreting a string and I hope you can help me.
I have to convert a string, or a word in a number. Like five hundred fifty in 550. I dont know exactly how to do it.
I was thinking to try to analize each word, but this seems like a huge code. Or i was thinking that maybe you can check in a table, but then the table should be huge(numbers should go up to millions)
Is there a smarter way? What do you suggest?
Thank you very much
|
|
|
|
|
There is a simpler way of doing it. In fact if you google it, you will see many examples on the web. Here [^] is one such example.
|
|
|
|
|
Here is an algorithm that should do it:
1. search for the words that indicate a power of 1000 (thousand, million, etc);
2. each of those delimit a number that ranges from 1 to 999; and for each of them:
3. search for "hundred", what is to the left of it has to be a digit; what is to the right of it has to be less than 100.
So you still need some code that deals with 1..99; and you may need to handle (ignore?) any "and" in the string.
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
|
OS Version: Windows XP Pro
boost Version: 1.44.0
Hi,
I want to monitor, whether a certain process is running.
The program of the process is written in C++ and is
a console app.
I've chosen the mutex concept, because I want to restrict usage
of the program's main to exactly one thread.
First I used the example from the boost site, which places the scoped_lock
within the main routine's block. But when the app was terminated via
the close button of the console window
the scoped_lock destructor was not called
which had a negative side effect: The mutex is associated with a file
in the All Users\Application Data tree,
directory boost_interprocess
and if this file is not deleted, the mutex can not be acquired, although
it is no more referenced by any application.
Hence I wrapped the mutex into a global object
(1) to instantiate it as soon as possible
(2) to release it under as many circumstances of program termination as possible via
the wrapper's destructor.
This is the wrapper's class - you can see
the mutex is
non-blocking and
controlled via a scoped lock
<br />
struct ApplicationLock<br />
{<br />
ApplicationLock() : appmutex(open_or_create, "SilvaCoreMutex"), applock(appmutex, try_to_lock)<br />
{}<br />
bool alreadylocked()<br />
{<br />
return (applock == 0);<br />
}<br />
private:<br />
named_mutex appmutex;<br />
scoped_lock<named_mutex> applock;<br />
};<br />
<br />
ApplicationLock appliclock;<br />
If the console window is closed, the desctructor is called and
the mutex released. But if the process is terminated due
to a crash or aborted via the task manager,
the mutex is not released. Even a system restart doesn't release it.
I thought a mutex should
be held in a memory shared area and exclusively depend on this shared area
and never depend on anything which is stored in the file system.
How can I get rid of that mutex, when it is no more referenced
by any application. Have I chosen the wrong concept? Have I
misunderstood the boost mutex technique?
Thanks in advance
Werner
|
|
|
|
|
If you have time, you can try reading Lock & Wait Synchronization in C++[^]
Why can't you prevent your process from being spawned by counting the number of running instances and not creating a new instance if one already exists?
Then you only need a lock on that tiny code block.
|
|
|
|
|
Thank you.
Then I would hold the counter in a shared memory area.
Which technique would you recommend for the shm? I would prefer one,
which is platform independent to a high degree.
I've experimented with the shared memory class in boost::interprocess.
The boost shm object again seemed to create a file in the Application Data dir.
I don't like this so much, because it is dependent on access restrictions
to the fs.And this would not be necessary, because I'm just using ram.
Werner
|
|
|
|
|
then try locking a file in the temp directory.
"If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams
|
|
|
|
|
Thank you,
this I think is basically ok,
but I would like the lock to be deleted, when the process, that created it crashes,
which is not the case with a boost::named_mutex or a temp file,
and on windows using such directories like temp and appdata a.s.o is always fuss, because they are rarely organised the same on all Windows NT systems and often not named the same and often not defined within the same system variable.
If I had read the boost documentation before
I had not been so surprised, that the mutex and the shm are opening a file
because these objects have 'kernel or filesystem' persistence
which on Windows seems to be always filesystem.
Such objects need an explicit call to their remove function to remove the file.
What I'm looking for is an interprocess object with process persistence.
Cheers
Werner
modified on Wednesday, January 26, 2011 6:46 PM
|
|
|
|
|
I'm not sure I understand what you intend to do with the "Mutex". It seems that you simply want to ensure that only one instantiation of the application runs. You haven't been clear what the "2nd" instantiation, the one who finds the "lock" taken will do as a result. Will it "exit", will it "wait for the 1st application to exit".
Depending on your intended use, there may be different approaches. A Mutex might not be the appropriate solution.
|
|
|
|
|
Hi,
the application which I'm working on is based on
a client server architecture
|java gui| <- gsoap -> |c++ server|
where the server is a windows or unix program, which embeds the business logic.
I want to make a gui for users, who don't need to know about that
and simply start the gui as if it was the whole app.
Thus the gui is managing server instantiation -
gui started && server not running => gui starts server.
gui started && server running => gui uses server.
server has no more session within timeout => server exits gracefully.
So what I actually would need is a singleton server and this would mean
to query the OS for the existence of the server process.
Java has no method to
query process lists on a system independent level or to
check, whether there is a certain process running -
there's just rudimentary support for process control.
Java is gui standard here. So I made a little app (nmmutex) which is
supposed to control a named mutex for the server's main thread. This app
exits always and writes it's result (acquired, not acquired) to the
return code. The mutex is queried in a non-blocking manner (try_to_lock).
Java can run that process via Runtime.exec.
Using that mutex, the server itself may control, whether there is already
an instance running. It also can try_to_lock the mutex, and if it's not
available, may return. The server itself could also take the role of nmmutex,
i.e. to query the mutex.
The caveat of using the mutex is, as far as I understood, that boost
interprocess objects like mutex and shared memory due to portability have
'kernel or filesystem' persistence. On windows it's filesystem persistence.
So if the server crashes, it might not be restartable even after a reboot.
And the user can't tell why.
I tend to dislike the mutex idea meanwhile, although using it seemed logical
to me first: I wanted to restrict use of server's main block to a single thread.
I could try to get a soap session at gui startup and assume the server does not
run when it fails. Or maybe there's a library which hides querys to the os,
like process list, behind a portable interface.
Cheers
Werner
modified on Thursday, January 27, 2011 4:00 AM
|
|
|
|
|
Thanks for the details. So basically, you do not need the "synchronization" aspect of a mutex, just the "global name" aspect to check for exists / doesn't-exist check. I have used two methods for exactly this problem. Both methods "reset" when the image exits because Windows cleans up the objects.
One is to use "named pipes". This method has been suggested by other people in Code Project. You create a pipe with a known name agreed upon by the two processes. When you say "gui uses server", I assume you communicate in some way, you might even use pipes. I prefer this method when I need to also communicate between the processes as it provides for both a "single server instance" and the "interprocess communication".
Here's a routine I use to create an "inbound" pipe (the server code) in such a way as there will be only 1 instance. The error INVALID_HANDLE_VALUE indicates that you cannot create the pipe which is taken to mean that the pipe is already in use. I've "scrubbed" this a little to remove things I cannot share with you.
#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000 // make VC 6.0 happy
#endif
#define RTLOCALIPC_WIN_SDDL \
SDDL_DACL SDDL_DELIMINATOR \
SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_GENERIC_ALL ";;;" SDDL_NETWORK SDDL_ACE_END \
SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_GENERIC_ALL ";;;" SDDL_EVERYONE SDDL_ACE_END \
SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_FILE_ALL ";;;" SDDL_LOCAL_SYSTEM SDDL_ACE_END
HANDLE CreateInboundPipe(CString PName, bool first)
{
CString ts;
SECURITY_ATTRIBUTES *SecAttrs = NULL;
DWORD dwOpenMode;
DWORD dwPipeMode;
PSECURITY_DESCRIPTOR pSecDesc = NULL;
ConvertStringSecurityDescriptorToSecurityDescriptor(RTLOCALIPC_WIN_SDDL, SDDL_REVISION_1, &pSecDesc, NULL);
SecAttrs = (SECURITY_ATTRIBUTES *)malloc(sizeof(SECURITY_ATTRIBUTES));
SecAttrs->nLength = sizeof(SECURITY_ATTRIBUTES);
SecAttrs->lpSecurityDescriptor = pSecDesc;
SecAttrs->bInheritHandle = FALSE;
dwOpenMode = PIPE_ACCESS_DUPLEX | (first ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0);
dwPipeMode = PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT;
ts.Format("\\\\.\\pipe\\%s", PName);
ThePipe = CreateNamedPipe(ts, dwOpenMode, dwPipeMode, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, NMPWAIT_USE_DEFAULT_WAIT, SecAttrs);
free(SecAttrs);
LocalFree(pSecDesc);
return ThePipe;
}
The "client" can then try to connect to the same pipe name and if it discovers that the server isn't available, it could start an instance of the server. Again "scrubbed" a bit since I can't cut / paste the entire routine.
HANDLE ConnectToServer(CString PName, bool NoRetry)
{
CString ts;
int retry = 0;
ts.Format("\\\\.\\pipe\\%s", PName);
while (1)
{
ThePipe = CreateFile(ts, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if ((NoRetry) || (ThePipe != INVALID_HANDLE_VALUE))
break;
if (GetLastError() == ERROR_PIPE_BUSY)
{
WaitNamedPipe(ts, NMPWAIT_WAIT_FOREVER);
}
else
{
if (retry++ == 0)
{
}
if (retry > (GIVE_UP_TIMER / GIVE_UP_SLEEP))
break;
Sleep(GIVE_UP_SLEEP);
}
}
if (ThePipe != INVALID_HANDLE_VALUE)
{
DWORD dwMode = PIPE_READMODE_MESSAGE;
SetNamedPipeHandleState(ThePipe, &dwMode, NULL, NULL);
Connected = true;
}
return ThePipe;
}
since these are part of a larger Class, there are some Class Members I don't show, like ThePipe, the Timeouts, etc. But you should be able to figure those out.
The other method I use, especially for "short lived processes" is to simply open a known file with GENERIC_WRITE, in other words, take out an exclusive access lock on a shared file. Only 1 process can do this and the kernel manages that. The kernel will "close" the access when the image exits so cleanup is easy. If the "client" can get the exclusive access lock, then the server is not running so it can release the file and then start the server. This method does suffer from some timing issues and you'll need a retry mechanism like the one used for the pipes to avoid some startup problems.
|
|
|
|
|
Is there any way to find which interface a UDP packet was received on? I can't rely on using the IP addresses since it is possible (and fairly common for out of the box setup) that the device I'm talking to has a misconfigured IP.
In other words,
If a new device out of the box has a 10.1.0.1 address and my NIC that I am using to plug into it has a 192.x.x.x address, my program will eventually try broadcasting to it and a reply will come back with source address 10.1.0.1 on that NIC. This is why I cannot use IP addresses to try to determine which interface received the message.
Thanks,
Dave
|
|
|
|
|
You will need to capture entire packet frame with Mac address still in tact. One way is to use a packet capture library like Winpcap. But I certainly doubt that you can get it using normal socket operations; Since it strips off the packet headers before giving it to user application.
|
|
|
|
|
CRegKey regkey;
TCHAR modbuffer[MAX_PATH];
DWORD dwModPathLen = ::GetModuleFileName(NULL, modbuffer, _countof(modbuffer));
if (dwModPathLen == 0 || dwModPathLen == _countof(modbuffer))
return;
CString strCanonFileName = modbuffer;
strCanonFileName.Replace(_T("%"), _T("%%"));
CString regbuffer;
regbuffer.Format(_T("\"%s\""), strCanonFileName);
CString csKeyName = _T("MyProgram");
HKEY hkeyCR = HKEY_LOCAL_MACHINE;
if (bAutoRun)
{
if (regkey.Open(hkeyCR, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"),
KEY_ALL_ACCESS) != ERROR_SUCCESS)
{
regkey.SetStringValue(csKeyName, regbuffer);
regkey.Close();
}
}
else
{
if (regkey.Open(hkeyCR, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), KEY_READ) != ERROR_SUCCESS)
{
regkey.RecurseDeleteKey(csKeyName);
regkey.Close();
}
}
}
The Exception is m_Key is NULL. My system is windows 7. Is it the Priviledge problem?
modified on Tuesday, January 25, 2011 8:54 PM
|
|
|
|
|
Check what Open returns, it should explain the problem.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Leela: Fry, you're wasting your life sitting in front of that TV. You need to get out and see the real world.
Fry: But this is HDTV. It's got better resolution than the real world <
>Nothing is free in the universe.<
|
|
|
|
|
yu-jian wrote: The Exception is m_Key is NULL.
There isn't an 'm_key ' in posted code.
yu-jian wrote: s it the Priviledge problem?
Probably. However, Checking API calls return values would help.
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.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
yu-jian wrote: Is it the Priviledge problem?
If you run the program as admin and it works, then the answer is Yes.
|
|
|
|
|
yu-jian wrote: Is it the Priviledge problem?
No it's the coding problem. In both of your Open() statements you are checking if the return code is not equal to ERROR_SUCCESS , and proceeding if it is not. These tests should be reversed so you only proceed if the return is equal to ERROR_SUCCESS . Also you should capture the returned value as it will help you to diagnose what has gone wrong.
I must get a clever new signature for 2011.
|
|
|
|
|
OK. The return value was 5.
Now this problem resolved. Under win7 it needs Administrator priviledge to run. Under the xp, It can operate register directly.
|
|
|
|
|
|
what is a bitwise copy in c++ done by default constructor and what is shadow copy and deep copy ?
|
|
|
|
|