Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

STL map and unicode

90 views
Skip to first unread message

Vincent RICHOMME

unread,
Feb 1, 2007, 1:28:43 PM2/1/07
to
Hi,

I would like to use a hashtable to associate a windows unicode string
(define as a ulong *) to a list.
So first I try this :

typedef std::list<FunctionInfo> FuncList;
FuncList g_FuncList;

typedef std::map<LPWSTR, FuncList> ModuleList;
ModuleList g_ModuleList;


void Hook_API( LPWSTR p_wszModuleName,
LPWSTR p_wszFunctionName,
PROC p_pfnNewProc
)
{
ModuleList::iterator l_it;

l_it = g_ModuleList.find( (LPWSTR)p_wszModuleName );
if (l_it == g_ModuleList.end() ){
...
}
}

when I try this if I call three times my function with the same
parameter (L"coredll.dll" for instance) I will have
three keys in my hashtable

Hook_API(L"coredll.dll", "func1", NULL);
Hook_API(L"coredll.dll", "func2", NULL);
Hook_API(L"coredll.dll", "func3", NULL);

So I should have only one key in my hash table (coredll.dll) but it's
not the case


I think it's because map considers LPWSTR as a pointer and not as a
string. So LPWSTR is always different since address is different.

Maybe I should use std::string but in this case how to do with unicode
string.

Ondra Holub

unread,
Feb 1, 2007, 3:36:41 PM2/1/07
to

Vincent RICHOMME napsal:

You have to specify comparing function for map. With the default
comparing function are compared pointers (L"hello" and L"hello" may or
need not be on the same place in memory, so pointers may or need not
to be same):

struct Comparator
{
bool operator()(const LPWSTR s1, const LPWSTR s2)
{
// here implement your function. I do not know LPWSTR, because
I do not use windows
// but for char* it would look this way:
// return strcmp(s1, s2) < 0;
// So simply replace strcmp with comparing function for LPWSTR
}
};

typedef std::map<LPWSTR, FuncList, Comparator> ModuleList;

Satish

unread,
Feb 1, 2007, 5:09:15 PM2/1/07
to

You should declare a static/global/member variable and declare
L"coredll.dll"/
and pass this variable each time instead of explicitly calling like
L"coredll.dll". Something like calling twice
Hook_API(L"coredll.dll", "func2", NULL); you are passing 2 different
pointers each time. LPWSTR is Long pointer to wide string is a macro
for wchar_t*. You could try using wstring. Check a related article
at
http://groups.google.com/group/borland.public.cppbuilder.language.cpp/browse_thread/thread/cde977de386b7106/87f9968c341cf39%2387f9968c341cf39

Kirit Sælensminde

unread,
Feb 1, 2007, 8:35:10 PM2/1/07
to

The simplest thing is to use std::wstring which uses wchar_t (16 bit
on Windows).

You have a lot of C style code in there. This line here:

l_it = g_ModuleList.find( (LPWSTR)p_wszModuleName );

Is particularly nasty. Why the C style cast on the type which is
already LPWSTR? This is a really bad habit to get into as you are
subverting the type system and you lose many of the benefits of C++
stronger typing.

Lost of Microsoft's API calls are not const correct (they seem to be
trying to change this, but it's not 100% yet). That's no reason for
you to copy them though.

> void Hook_API( LPWSTR p_wszModuleName,
> LPWSTR p_wszFunctionName,
> PROC p_pfnNewProc
> )

Here you should really be using LPCWSTR (I think it is) or at least
this:

void Hook_API( const LPWSTR p_wszModuleName,
const LPWSTR p_wszFunctionName,
PROC p_pfnNewProc
);

Better yet would be this:

void Hook_API( const std::wstring &moduleName, const std::wstring
&functionName, PROC newProc );

The Hungarian notation that you use was originally meant to help
overcome inadequacies of the type system. There's no real reason to
use them in languages with better type systems like C++.


K

0 new messages