Problème conversion ASCII -> UTF16


Nekuzor

Recommended Posts

Bon voila mon problème, lorsque je déclare un pointeur sur une chaine de caractère 16 bits au moment du détachement de ma dll (donc l'opération doit se faire avant que la dll se détache) cella me fait une erreur du style ("la mémoire ne peut être 'read'" ou "'written'", en fonction de l'heure ^^).

[cpp]

bool WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )

{

if(fdwReason == DLL_PROCESS_ATTACH)

{

HookFunctions();

}

else if(fdwReason == DLL_PROCESS_DETACH)

{

MesPlugins.Unload();

UnHookFunctions();

}

return true;

}

[/cpp]

alors voici ici vous pouvez le voir, je vérifie donc si ma dll est attachée au processus ou détachée.

et avant que celle-ci soit détachée je demande de déchargé les plugins.

Dans mon plugins, au moment ou on veut le décharger ( freelibrary(); )

j'appel une fonction qui genere un pointeur sur une chaine de caractere 16 bits (LPWSTR)

[cpp]

// UTF16

LPWSTR wstrTitle = new WCHAR[256];

memset(wstrTitle, 0, sizeof(WCHAR)*256);

[/cpp]

et c'est au niveau de cette ligne la que ca plante :

[cpp]

LPWSTR wstrTitle = new WCHAR[256];

[/cpp]

le pire de tout dans l'histoire c'est que malgré l'erreur d'acces en mémoire, l'entierté du code s'exécute correctement et fait ce que je lui demande ... mais j'aime pas laisser des erreurs :P

Celui qui me trouve la solution à mon problème ... aura droit à un bisou :$

Link to comment
Share on other sites

memset est la fonction qui permet de un espace mémoire dans lequel on met chaque caractère d'uné chaine a '\0' pour pouvoir être ecrit apres.

et WCHAR de la variable sur lequel pointe le pointeur et donc on initialise une chaine de caratères de type WCHAR à '\0'.

Tu devrais savoir, qu'une chaine de caractère dois être zéro terminé ;)

[cpp]

LPWSTR wstrTitle = new WCHAR[256];

[/cpp]

revient au même que, juste une question de nouvelle écriture

[cpp]

LPWSTR wstrTitle = (LPWSTR) malloc(sizeof(WCHAR)*256);

[/cpp]

Voici un petit exemple en application console :

#include "stdafx.h"
#include 
#include 
int _tmain(int argc, _TCHAR* argv[])
{
LPWSTR  wstrTitle  = (LPWSTR) malloc(sizeof(WCHAR)*256);
memset(wstrTitle,'\0',sizeof(WCHAR)*256);
lstrcpy((LPTSTR)wstrTitle,TEXT("test"));
printf("%s",wstrTitle);
system("pause");
return 0;
}

Link to comment
Share on other sites

Problème résolut :P

alors explication :

J'utilisais donc une gestion dynamique de la mémoire (free / delete), j'ai donc remplacé par une variable déclarée statiquement (ca change rien vu qu'elle se trouve dans la fonction appelée et donc détruite en fin).

[cpp]

// UTF16

LPWSTR wstrTitle = new WCHAR[256];

memset(wstrTitle, 0, sizeof(WCHAR)*256);

// convert ASCII to UTF16

int nLen = MultiByteToWideChar(CP_ACP, 0, title.GetBuffer(), -1, NULL, NULL);

MultiByteToWideChar(CP_ACP, 0, title.GetBuffer(), -1, wstrTitle, nLen);

[/cpp]

devient ->

[cpp]

// UTF16

WCHAR wstrTitle[256];

memset(wstrTitle, 0, sizeof(CHAR)*256);

// Conversion ASCII vers UTF16

int nLen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)Title, -1, NULL, NULL);

MultiByteToWideChar(CP_ACP, 0, (LPCSTR)Title, -1, (LPWSTR)wstrTitle, nLen);

[/cpp]

pour ceux que ca interesse, la fonction complette utilisant cette conversion sert à envoyer via SendMessage, un titre et artiste à msn pour mettre dans le commentaire le morceau que l'on écoute.

Sauf que dans le cas présent c'est pour mettre l'ip du serveur sur lequel l'on se trouve.

voici la source :

void SetSongText(const char * Hostname,const char * IP, int Show)
{
HWND msnui = NULL;
COPYDATASTRUCT msndata;

// ASCII
char Title[256];
memset(Title,'\0',sizeof(Title));
sprintf(Title,"\\0Music\\0%i\\{0} - {1}\\0%s\\0%s\\0\\0\\0",Show,Hostname,IP);
// UTF16
WCHAR wstrTitle[256];
memset(wstrTitle, 0, sizeof(CHAR)*256);

// Conversion ASCII vers UTF16
int nLen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)Title, -1, NULL, NULL);
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)Title, -1, (LPWSTR)wstrTitle, nLen);
msndata.dwData = 0x547;
msndata.lpData = (void*)wstrTitle;
msndata.cbData = (nLen*2)+2;
while (msnui = ::FindWindowEx(NULL, msnui, "MsnMsgrUIManager", NULL))
{
 ::SendMessage(msnui, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&msndata);
}
}

Exemple d'utilisation:

SetSongText("Playing Counter-strike","127.0.0.1",1);

Msn affichera : d-b Playing Counter-strike - 127.0.0.1

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.