conversione stringhe ANSI in C++/CLI tra mondo managed e unmanaged

Promemoria sulla conversione di stringhe ANSI tra mondo managed e unmanaged:

Managed->Unmanaged       Marshal::StringToHGlobalAnsi()

Alla fine occorre ricordarsi di deallocarla usando Marshal::FreeHGlobal()

Unmanaged->Managed       Marshal::PtrToStringAnsi()

 

Posted by sergio | with no comments

È uscito il primo masterizzatore blue ray: 25 GB in 42 minuti

Pioneer ha messo in vendita il primo masterizzatore blue ray. È ancora un po' caro, come anche i dischi. Può masterizzare solo un layer, per cui la capacità è di "soli" 25 GB anzichè i 50 GB del dual layer. E' in grado di masterizzare i 25 GB di un disco completo in 42 minuti.

L'articolo è qui: http://www.extremetech.com/article2/0,1697,1980121,00.asp

In 25 GB ci starebbero + di 5000 MP3: la prossima autoradio la voglio con il lettore blue ray ;)

(quanto costi riempire legalmente un disco di MP3, lo lascio come semplice esercizio per il lettore)

Posted by sergio | with no comments

quando la soluzione è semplice... se la sai! Qual è l'equivalente del null di C#, in C++/CLI ?

SortedDictionary<String^, Int32>^ dic = 0; // sbagliato!

Assegnare 0 a un "hat" in C++/CLI, come in questo mio pezzo di codice, "it just doesn't work"!

L'equivalente del null di C#, in C++/CLI è la parola chiave nullptr

(Un "hat" in C++/CLI equivale a un reference di C#. Lo hanno chiamato "hat" per distinguerlo dal reference del C++ e per via del simbolo utilizzato per rappresentare un reference managed, cioè il ^)

 

 

Posted by sergio | with no comments

Solution con C# che chiama una DLL C++ managed che chiama una DLL C++ nativa

Ho creato una solution con Visual Studio 2005, che contiene un'applicazione in C# con Windows Forms: l'interfaccia utente. Questa chiama una DLL scritta in C++/CLI, la cui funzione è di incapsulare le funzioni esportate da una DLL scritta in codice nativo. Anche la DLL in codice nativo è inclusa nella solution, come sorgente C++. Ho quindi aggiunto come reference del progetto in C#, il progetto in C++/CLI e come reference per quest'ultimo, ho aggiunto il progetto della DLL in C++ nativo.

La  build della solution funziona perfettamente. Ma lanciando l'applicazione veniva scatenata un'eccezione di tipo FileNotFoundException:

The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Ma non diceva qual era il modulo mancante. Dopo aver perso un po' di tempo con Filemon, ma senza risultati, ho scoperto che specificare i reference non era sufficiente. Quando si mescolano progetti C# e C++ in questo modo occorre specificare che la directory di output del progetto in C# si trova nella directory <miasoluzione>\Debug. In sostanza basta specificare ..\Debug come Output Path nelle proprietà del progetto C#.

Posted by sergio | with no comments

Da DOS a .NET, lettura di file OEM

Per aprire con uno StreamReader un file generato in DOS, contenente caratteri OEM, quali ad esempio il "pallino" '°', occorre specificare nel costruttore l'encoding OEM.

StreamReader sr = new StreamReader(@"C:\temp\chars.txt", 
   System.Text.
Encoding.GetEncoding(
      System.Globalization.
CultureInfo.CurrentCulture.TextInfo.OEMCodePage));
Posted by sergio | with no comments

Microsoft Visual Studio Version Selector

Facendo doppio click su una soluzione, parte automaticamente Visual Studio 2003 o Visual Studio 2005 a seconda della versione usata per creare la soluzione. A patto, ovviamente, di averli entrambi installati ;)

Questo funziona perché l'installazione di Visual Studio 2005 associa nel registry l'estensione sln al Microsoft Visual Studio Version Selector  

%ProgramFiles%\Common Files\Microsoft Shared\MSEnv\VSLauncher.exe

Posted by sergio | with no comments

OT: The Scene, la soap opera per gli hacker

  • Meglio di matrix
  • Più addictive di LOST

Le avventure di un gruppo di pirati facenti parte della "scena

Siamo alla 18-esima puntata. Io non vedo l'ora che esca la prossima.

http://www.welcometothescene.com/

Un consiglio, cominciate a vederlo dalla prima puntata ;)

 

Posted by sergio | with no comments

OT: google maps ha aggiornato la cartografia su Torino!

Ho scoperto che in occasione delle olimpiadi, google ha aggiornato tutte le foto riguardanti Torino!

Inoltre hanno messo online le informazioni cartografiche, che prima erano disponibili solo usando il client di google earth.

Stadio Olimpico

Inoltre esiste un modello 3D freeware di Torino. Mi ha dimostrato che è ora che aggiorni la mia scheda grafica, quindi non posso giudicarlo...

E' disponibile per il download da qui: http://www.ultramundum.org/

Posted by sergio | with no comments

Bureautique

Che i francesi traducessero tutto, lo sappiamo bene. Sappiamo tutti che "ordinateur" significa "computer" e "octet" significa "byte". Forse qualcuno in meno sa anche decifrare "KO", "MO" e "logiciel" (kbyte, megabyte e software). Ma che avessero una parola apposta per "office automation" non lo sapevo proprio:

Bureautique

Ah ben, ça alors.. je ne le savait vraiment pas!

Posted by sergio | with no comments

messaggi di errore molto molto molto complicati in C++ con STL

Ho appena perso mezz'ora per un problema riassumibile con questo programmino minimale:

#include <map>
// #include <string>

int main()
{
	using namespace std;
	map<string,string> m;

	m["sergio"] = "sergio";
	return 0;
}

Il Visual C++ genera una sfilza di errori localizzati nel sorgente della libreria standard ! Non c'è nessun riferimento alla riga del mio sorgente che scatena l'errore. Se il programma fosse più complicato di questo ;-) diventerebbe difficile capire che l'errore è dovuto all'assenza del file header. L'unica soluzione è commentare pezzi di codice finché l'errore non sparisce.

Con il gcc la situazione è simile, ma almeno compare l'indicazione della riga nel mio sorgente che ha scatenato la sfilza di errori precedenti, se si ha la pazienza di leggere bene tutto l'output ;-)

L'esperienza insegna che quando si ottiene una sfilza di errori del genere, la prima cosa da andare a controllare è se sono stati inclusi tutti i file header.

Seguono gli errori generati dal Visual C++

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
provamappa.cpp
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(1170) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(138) : while compiling class-template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
with
[
_Ty=std::string
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\map(67) : see reference to class template instantiation 'std::less<_Ty>' being compiled
with
[
_Ty=std::string
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(23) : see reference to class template instantiation 'std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,_Mfl>' being compiled
with
[
_Kty=std::string,
_Ty=std::string,
_Pr=std::less<std::string>,
_Alloc=std::allocator<std::pair<const std::string,std::string>>,
_Mfl=false
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(65) : see reference to class template instantiation 'std::_Tree_nod<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<std::string,std::string,std::less<std::string>,std::allocator<std::pair<const std::string,std::string>>,false>
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(87) : see reference to class template instantiation 'std::_Tree_ptr<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<std::string,std::string,std::less<std::string>,std::allocator<std::pair<const std::string,std::string>>,false>
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(105) : see reference to class template instantiation 'std::_Tree_val<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<std::string,std::string,std::less<std::string>,std::allocator<std::pair<const std::string,std::string>>,false>
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\map(77) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<std::string,std::string,std::less<std::string>,std::allocator<std::pair<const std::string,std::string>>,false>
]
provamappa.cpp(7) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
with
[
_Kty=std::string,
_Ty=std::string
]
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(1170) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xtree(1170) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xutility(655) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xutility(655) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xutility(655) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\utility(73) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\utility(73) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string'
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\utility(73) : see declaration of 'std::operator`<''
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139) : error C2676: binary '<' : 'const std::string' does not define this operator or a conversion to a type acceptable to the predefined operator

 

 

Mentre il g++ genera questi errori

/usr/include/c++/3.3/bits/stl_pair.h: In instantiation of `std::pair<const std::string, std::string>':
/usr/include/c++/3.3/bits/stl_tree.h:123: instantiated from `std::_Rb_tree_node<std::pair<const std::string, std::string> >'
/usr/include/c++/3.3/bits/stl_alloc.h:232: instantiated from `static _Tp* std::__simple_alloc<_Tp, _Alloc>::allocate(unsigned int) [with _Tp = std::_Rb_tree_node<std::pair<const std::string, std::string> >, _Alloc = std::__default_alloc_template<true, 0>]'
/usr/include/c++/3.3/bits/stl_tree.h:564: instantiated from `std::_Rb_tree_node<_Val>* std::_Rb_tree_alloc_base<_Tp, _Alloc, true>::_M_get_node() [with _Tp = std::pair<const std::string, std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >]'
/usr/include/c++/3.3/bits/stl_tree.h:579: instantiated from `std::_Rb_tree_base<_Tp, _Alloc>::_Rb_tree_base(typename std::_Rb_tree_alloc_base<_Tp, _Alloc, std::_Alloc_traits<_Tp, _Allocator>::_S_instanceless>::allocator_type&) [with _Tp = std::pair<const std::string, std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >]'
/usr/include/c++/3.3/bits/stl_tree.h:730: instantiated from `std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Rb_tree(const _Compare&, typename std::_Rb_tree_base<_Val, _Alloc>::allocator_type&) [with _Key = std::string, _Val = std::pair<const std::string, std::string>, _KeyOfValue = std::_Select1st<std::pair<const std::string, std::string> >, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >]'
/usr/include/c++/3.3/bits/stl_map.h:144: instantiated from `std::map<_Key, _Tp, _Compare, _Alloc>::map() [with _Key = std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >]'
provamap.cpp:10: instantiated from here
/usr/include/c++/3.3/bits/stl_pair.h:73: error: `std::pair<_T1, _T2>::first'
has incomplete type
/usr/include/c++/3.3/bits/stringfwd.h:56: error: declaration of `const struct
std::string'
/usr/include/c++/3.3/bits/stl_pair.h:74: error: `std::pair<_T1, _T2>::second'
has incomplete type
/usr/include/c++/3.3/bits/stringfwd.h:56: error: declaration of `struct
std::string'
provamap.cpp: In function `int main()':
provamap.cpp:12: error: no match for 'operator[]' in 'm["sergio"]'
/usr/include/c++/3.3/bits/stl_map.h:312: error: candidates are: _Tp&
std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key =
std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc =
std::allocator<std::pair<const std::string, std::string> >]

 

 

Posted by sergio | with no comments

Sony abbandona AIBO, il robot cane.

Il piano di ristrutturazione della Sony prevede l'abbandono di AIBO!

 

Image Hosted by ImageShack.us

La notizia è qui

Posted by sergio | with no comments

overload dell'operatore () in C++

Oggi ho usato uno degli overload "strani" che si possono fare in C++. L'overload dell'operatore "aperta tonda, chiusa tonda".

class Converter
{
public:
	Converter(int num, int den)
	{
		m_num = num;
		m_den = den;
	}
	int operator()(int x)
	{
		return FT_MulDiv(x, m_num, m_den); 
	}
private:
	int m_num;
	int m_den;
};
E poi l'ho usata in questo modo: 
Converter cx(face->size->metrics.x_ppem * 64, face->units_per_EM);
Converter cy(face->size->metrics.y_ppem * 64, face->units_per_EM);
cout << "desc " << cy(face->descender) << endl;
cout << "xMin " << cx(face->bbox.xMin) << endl;
cout << "xMax " << cx(face->bbox.xMax) << endl;
cout << "yMin " << cy(face->bbox.yMin) << endl;
cout << "yMax " << cy(face->bbox.yMax) << endl;

l'oggetto viene usato a tutti gli effetti come se fosse una funzione. Ogni istanza però della classe è una funzione diversa. Si può dire che questa classe rappresenta una "famiglia di funzioni".
Questa tecnica viene usata nella STL per i "functor". Ad esempio per la classe unary_function<Arg, Result>

Posted by sergio | with no comments

Compilare FreeType con Jam per Windows usando il formato 8.3

Per un bellissimo progetto cross-platform Windows/Linux, sto valutando di utilizzare FreeType, la libreria open source che permette di gestire i font.

Per compilare questa libreria esiste un tool: Jam, che promette di effettuare la compilazione sia su Windows che su Linux che su MAC che su Solaris, etc... , semplicemente impostando un paio di variabili di ambiente e scrivendo

C:\dev\FreeType2>jam

nella directory principale del progetto. Ma come quasi sempre, nel mondo open-source niente è gratis ;).

Niente è gratis, nel senso che bisogna sempre dedicarci un sacco di tempo...

Come prima cosa occorre compilare jam, il che avviene eseguendo un makefile, che provvede a compilare una prima versione di jam, jam0.exe, che poi provvede a compilare jam.exe.

Per compilare jam0.exe è sufficiente avere le variabili ambiente del Visual C++ in modo da poter eseguire nmake.

Ma per generare jam.exe viene usato un script che usa un paio di variabili di ambiente, JAM_TOOLSET e VISUALC. Quest'ultima deve contenere il percorso del compilatore.

Facile.

Però non funziona.

Perché se il percorso contiene degli spazi, e si da il caso che la path di visual studio ne contenga parecchi, vengono generati dei percorsi mostruosamente sbagliati.

Al primo impulso, "lo fixo io questo bug!", mi sono scontrato contro un muro di granito: Il problema dipende da come vengono gestiti gli script con le direttive per la compilazione, per cui avrei dovuto modificare l'interprete degli script, scassando chissà quante altre cose.

Dopo aver passato letteralmente ore su google, cercando cose come "embedded space", "embedded blank", jam, freetype, trouble, etc... ho trovato il workaround più vergognoso del mondo, che però ha "quasi" funzionato. Specificare il percorso usando il formato 8.3 (cioè anziché scrivere "program files" si deve scrivere "program~1" e così via.)

questo è il build.bat che ha funzionato:

set VISUALC=C:\Progra~1\Micros~1.NET\vc7
set JAM_TOOLSET=VISUALC
nmake -f builds\win32-visualc.mk

per risalire ai nomi in formato 8.3 basta fare

dir /x

Ha "quasi funzionato" perché poi ho anche dovuto copiare un po' di librerie da .\platformsdk\lib a .\lib, ma alla fine ha funzionato.

Ora mi prendo una vacanza in

                      **      **
       ******         **      **
     ********        ***     ***
    ****  ***        ***     ***
   ***    ***        **      **
   ***     **        **      **
  ***           *******************
  **            *******************
 ***                **      **
 **                 **      **
***                ***     ***
**                 **      **
**                 **      **
**            ******************
**            ******************
***       **     **      **
 **      ***     **      **
 **** *****     ***     ***
  ********      **      **
   *****        **      **

 

 

Posted by sergio | with no comments

La falla di sicurezza dei WMF non era una backdoor, parola di Mark Russinovich

Recentemente c'è stata una polemica sulla falla si sicurezza dei windows metafile.

Questa falla era dovuta all'esistenza, nel set di blocchi di un  metafile, del blocco SetAbortProc. Questo blocco "mima" la corrispondente API, che permette di impostare una funzione di callback, richiamata durante una operazione di stampa, per permettere all'applicazione di interromperla. Il blocco SetAbortProc dei windows meta file fa esattamente questo: manda in esecuzione del codice contenuto all'interno del metafile stesso!

Steve Gibson sosteneva che evidentemente si trattava di una backdoor messa intenzionalmente da un programmatore Microsoft.

La sua congettura si riassume sostanzialmente nei seguenti punti:

  • non c'è bisogno dei blocchi SetAbortProc nei metafile
  • anche ammettendo che servano, il codice della funzione di callback non dovrebbe essere mai eseguito, se non a seguito di una condizione di abort, cosa che eseguendo dei windows metafile non dovrebbe mai capitare
  • il codice della callback veniva eseguito solo impostando una lunghezza errata del blocco della SetAbortProc
  • windows eseguiva direttamente il contenuto del blocco anziché saltare a un determinato indirizzo all'interno dell'applicazione che eseguiva il metafile.

In un week end di follia ;) Mark ha smontato punto per punto questa teoria in questo interessantissimo post nel suo blog.

http://www.sysinternals.com/blog/2006/01/inside-wmf-backdoor.html

 

Posted by sergio | with no comments
More Posts Next page »