.NET Forum / Languages / Managed C++ / March 2005
Is there a simpler way?
|
|
Thread rating:  |
Fred Hebert - 17 Mar 2005 23:01 GMT I am trying to learn VC.NET and convert some Borland C++ applications. The syntax differences are killing me...
Is there an easy way to convert a hex string, entered by the user, to a binary string and back? This is the actual code I am trying to convert.
HexToBin(KeyEdit->Text.c_str(), BinKey, sizeof(BinKey));
HexToBin is a generic function that converts a string like "1b34c38d" to it's binary equivalent. There is also a BinToHex which reverses the process.
I know I could write a function to do it, but I threw all those routines away 10 years ago when I started using Borland.
I am hoping that someone can help, because I really don't want to have to go back to writing all of those little conversion routines.
Tim - 17 Mar 2005 23:56 GMT Please see the methods of Int32. Int32->Parse can convert hex string to binary, and Int32->ToString can convert from binary to hex string. Have fun!
> I am trying to learn VC.NET and convert some Borland C++ applications. The > syntax differences are killing me... [quoted text clipped - 13 lines] > I am hoping that someone can help, because I really don't want to have to > go back to writing all of those little conversion routines. Fred Hebert - 21 Mar 2005 15:30 GMT Not dealing with an integer. These are encryption keys, 128 and 256 byte strings that are entered by the user in hex.
Thanks anyway.
> Please see the methods of Int32. Int32->Parse can convert hex string > to binary, and Int32->ToString can convert from binary to hex string. > Have fun! doug mansell - 18 Mar 2005 02:32 GMT sscanf might suit your purposes.
int nHex; if (1 == sscanf(KeyEdit->Text.c_str(), "%x", &nHex)) { // converted }
> I am trying to learn VC.NET and convert some Borland C++ applications. The > syntax differences are killing me... [quoted text clipped - 13 lines] > I am hoping that someone can help, because I really don't want to have to > go back to writing all of those little conversion routines. Fred Hebert - 21 Mar 2005 15:33 GMT Not dealing with an integer. These are encryption keys, 128 and 256 byte strings that are entered by the user in hex.
Thanks anyway.
> sscanf might suit your purposes. > > int nHex; > if (1 == sscanf(KeyEdit->Text.c_str(), "%x", &nHex)) { > // converted > } Martin Richter [MVP] - 18 Mar 2005 12:00 GMT Hallo Fred!
> I am trying to learn VC.NET and convert some Borland C++ applications. The > syntax differences are killing me... Why? Its C++
> Is there an easy way to convert a hex string, entered by the user, to a > binary string and back? This is the actual code I am trying to convert. [quoted text clipped - 7 lines] > I know I could write a function to do it, but I threw all those routines > away 10 years ago when I started using Borland. Even than you should be able to program and learn! SCNR...
> I am hoping that someone can help, because I really don't want to have to > go back to writing all of those little conversion routines. static inline TCHAR ByteToHex(int c) { return static_cast<TCHAR>((c<10) ? (c)+_T('0') : (c)-10+_T('A')); }
void BinToString(PCVOID pData, PTSTR pszOut, int iLen) { int iPos=0; const BYTE *pszStr = (const BYTE *)pData; while (iLen--) { BYTE byte = *pszStr++; BYTE uByte = (byte & 0xF0) >> 4, lByte = byte & 0xF; pszOut[iPos++] = ByteToHex(uByte); pszOut[iPos++] = ByteToHex(lByte); } pszOut[iPos] = '\0'; }
static inline int HexToByte(TCHAR c) { return (c>=_T('0') && c<=_T('9')) ? (c)-_T('0') : (c>=_T('A') && c<=_T('F')) ? (c)-_T('A')+10 : (c>=_T('a') && c<=_T('f')) ? (c)-_T('a')+10 : 0; }
static inline bool IsHexDigit(TCHAR c) { return c>=_T('0') && c<=_T('9') || ((c>=_T('a') && c<=_T('f')) || (c>=_T('A') && c<=_T('F'))); }
int StringToBin(PCTSTR pIn, PVOID pOut, int iLen) { if (iLen==-1) iLen = _tcslen(pIn)/2; memset(pOut,0,iLen); if (!pIn) return 0; TCHAR uByte, lByte; int iPos=0; PBYTE pszStr = static_cast<PBYTE>(pOut); while (iPos<iLen && IsHexDigit(uByte=pIn[0]) && IsHexDigit(lByte=pIn[1])) { *pszStr++ = static_cast<BYTE>(HexToByte(uByte)<<4 | HexToByte(lByte)); ++iPos; pIn += 2; } return *pIn ? 0 : iPos; }
HTH
 Signature Martin Richter [MVP] WWJD "In C we had to code our own bugs. In C++ we can inherit them." FAQ : http://www.mpdvc.de Samples: http://www.codeguru.com http://www.codeproject.com
Fred Hebert - 21 Mar 2005 15:56 GMT Thanks for the response. I realize it is C++, but the differences in syntax be Borland C++ and Microsoft C++ .NET are significant enough to be annoying. Couple this with the fact that many of the functions and components I am used to using are missing or different, and ... Well it's a pain.
Case in point: 1 line of code in Borland C++ requires 54 lines of code (your example) in MS C++ .NET. Before you get all excited, I realize this is just one routine and not a fair comparison of the two environments. It wasn't intend as a comparison.
From my perspective though, I feel that the evolution of programming languages should be making programming easier. Than's why we evolved from hand coded assembly to these higher level language compilers. I just find it frustrating to have to go back to writing all kinds of what I consider low level support routines.
Everyone is free to disagree, but what if you bought the latest BMW and found that power windows were no longer an option, or the only sound system was a mono AM radio?
I mean this is not a show stopper, and there are a lot of neat things, but there are also a few holes.
Ioannis Vranos - 21 Mar 2005 19:06 GMT > Thanks for the response. I realize it is C++, but the differences in > syntax be Borland C++ and Microsoft C++ .NET are significant enough to be [quoted text clipped - 19 lines] > I mean this is not a show stopper, and there are a lot of neat things, but > there are also a few holes. .NET API is more >=high level than VCL/CLX (more high level in some parts, about equally high level in other parts).
What you need is to read some up to date VC++ .NET book.
For VC++ 2003, a nice beginner to intermediate level book that you can read, and covers all .NET facilities, including multithreading, is "Visual C++ .NET How To Program" by Deitel.
http://vig.prenhall.com/catalog/academic/product/0,1144,0134373774,00.html
About your Borland C++ applications, why do you want to port them to .NET, since they can run as they are?
I would create my new applications in .NET and keep the old ones as they are.
Fred Hebert - 21 Mar 2005 21:12 GMT The reason for the port, is that we seldom write new programs, but rather evolve existing applications. We are an OEM for automation controllers, and our software allows the end user to control, program and monitor our hardware. I am purposely being a little fuzzy because I don't wan to be accused of advertising our products here.
Anyhow, one of my current tasks, apart from evaluating the switch to MS compilers, is to add some additional functionally to the PC control program to correspond to enhancements in one of our automation controllers.
I am not going to spend 2 years redeveloping the app when I can spend a few days or a couple of weeks just adding a few new dialogs. We strongly embrace the concept of modular reusable code and I don't want to switch to a new environment which makes 16 years of reusable code obsolete.
I am not sure .NET has any real advantage for us. I was looking at the standard MSC and found the environment to be extremely primitive compared to the RAD environment to which I have become accustomed. I started looking at .NET because it was closer to the Borland stuff I was used to. (Probably has something to do with all of the Borland programmers that Microsoft hired.)
The main reason I am even looking at Visual Studio is that one of the senior management, who does a little programming, read something about the reusability and cross platform capabilities of .NET. So far I am not impressed.
You are not the first person who has recommended that we start over from scratch rather than try to convert old code to .NET. How is this protecting our investment?
Also I don't think .NET is going to resolve our Windows/Unix/Linux synchronization issues either. I mean I am having difficulty with the Windows conversion but am making some progress. Trying to get one of these apps to compile and run in a Linux environment is a non starter. At least now in our current environment we can share most of the tricky internal code (protocols, encryption, etc.). I think the device layer and the GUI are always going to be problematic.
The myth of "one size fits all" only works if everyone wants poorly fitting clothes. IMHO.
Perhaps in a business software (forms that update databases and basic reports) environment .NET works better.
Anyhow I really am trying to do a fair evaluation. I am asking for help just in case I am missing something. It wouldn't be the first time someone pointed out that I was looking in the wrong place and when I was directed the the right place things looked much better. I was hoping for something like "look under string conversion functions" and not "roll your own"...
I didn't think it was going to be this different and the built in docs were going to be this inadequate. I'll take your advice and get the book and go back to basics. Perhaps it will help me see the light. I just hope it's not a freight train ;-)
Ioannis Vranos - 22 Mar 2005 00:51 GMT > The reason for the port, is that we seldom write new programs, but rather > evolve existing applications. We are an OEM for automation controllers, [quoted text clipped - 23 lines] > the reusability and cross platform capabilities of .NET. So far I am not > impressed. Well, .NET is a CLI compliant VM and here you may download the CLI standard:
http://www.ecma-international.org/publications/standards/Ecma-335.htm
The CLI standard also defines its assembly language. A book for it:
http://www.amazon.com/exec/obidos/tg/detail/-/0735615470/qid=1091414100/sr=1-7/r ef=sr_1_7/102-2992266-3703320?v=glance&s=books
The main benefits of .NET, apart from garbage collection is that it provides a common API for all languages, and you can write different parts of a program in different languages.
C++ currently takes advantage of .NET by using the "managed extensions", however there is an upcoming C++/CLI standard and VC++ 2005 will use it instead of "managed extensions" (while the API remains the same of course).
C++/CLI design ideals, are not only C++ to be used for application programming as a first class citizen CLI (.NET) citizen, but *also* for .NET library writing (managed dlls).
With C++/CLI and VC++ 2005, C++ becomes the systems programming language of CLI (and .NET).
You may take a look at these:
http://msdn.microsoft.com/msdnmag/issues/05/01/COptimizations/default.aspx
http://pluralsight.com/blogs/hsutter/archive/2004/10/05/2672.aspx
http://blogs.msdn.com/branbray/archive/2003/11/07/51007.aspx
http://www.accu.org/conference/presentations/Sutter_-_Is_C++_Relevant_on_Modern_ Environments_%28keynote%29.pdf
And a page of mine:
http://www23.brinkster.com/noicys/cppcli.htm
With C++/CLI, C++ has two worlds: The unmanaged world and the managed world.
In the managed world every CLI (.NET) feature is provided separately from the unmanaged world features.
> You are not the first person who has recommended that we start over from > scratch rather than try to convert old code to .NET. How is this > protecting our investment? With C++ on .NET you can compile in mixed mode, that is combine unmanaged and managed code in the same application (for example you can extend an existing unmanaged application with managed code).
The problem in your case is that you are using a third party API (VCL/CLX) and Borland does not provide a .NET C++ compiler so far.
So you will have either rewrite everything that uses Borland stuff in .NET, wait for Borland to produce a .NET enabled C++ compiler and then simply extend your application from there, or use Delphi .NET, in the case that Delphi can work with C++ Builder dlls (I do not know). Also CLX was QT licensed by Trolltech: http://www.trolltech.com and they provide a VC++ .NET version as far as I know, in case you are using CLX and not VCL.
So in summary, the problem here is that you are using an API that VC++ does not come bundled with.
Myself have started windows programming with .NET directly (I do not know any Win32, MFC) and had checked VCL sometime in the past, so I do not know what happens in the case of unmanaged dlls. Perhaps it is possible to encapsulate your entire application as a dll that VC++ can work with, and then extend that application using VC++?
> Also I don't think .NET is going to resolve our Windows/Unix/Linux > synchronization issues either. I mean I am having difficulty with the [quoted text clipped - 3 lines] > internal code (protocols, encryption, etc.). I think the device layer > and the GUI are always going to be problematic. If you want complete *binary* portability to other CLI VMs (like Mono) you will have to rewrite your application in pure managed mode (possible only under upcoming VC++ 2005) for C++.
For source code portability only, there aren't any other C++ compilers supporting .NET so far in other platforms. .NET is relatively new after all (and will become the main Windows API after Longhorn, with its official name being WinFX).
> The myth of "one size fits all" only works if everyone wants poorly > fitting clothes. IMHO. [quoted text clipped - 13 lines] > and go back to basics. Perhaps it will help me see the light. I just > hope it's not a freight train ;-) No it is not a freight train, in the contrary it is very high level API. :-)
However if you can do so, you had better wait for VC++ 2005 that will use the new C++/CLI syntax (the switch from current "managed extensions" to C++/CLI is not that difficult, you will have to use just a different keyword for a current "managed extensions" keyword while also learn new keywords since C++/CLI replaces and extends managed extensions).
Plus, C++/CLI feels more C++ than current managed extensions. :-)
In summary, .NET is about this:
There is a CLI standard that defines the basics of a VM along with its assembly language. .NET is a CLI-compliant VM.
http://www.ecma-international.org/publications/standards/Ecma-335.htm
The benefits of a CLI VM is garbage collection, and that source code of all languages get compiled to an exe consisting of an Intermediate Language (IL), and is not a native exe.
The VM translates this IL to native code when the application is executed.
This also means that you can write different parts of an application in different languages (saved as managed dlls) and also use run-time libraries (dlls) from various languages in different languages. :-)
In summary, you save something as a dll library and use it from whatever language you want.
In C++ you can work in mixed mode (managed and unmanaged) and you can encapsulate unmanaged code with a managed interface and use it, thus making it possible to use the unmanaged code with managed-only languages (like VB).
Also with the upcoming C++/CLI, C++ becomes the systems programming language of .NET.
You can download the latest C++/CLI draft from here:
http://www.plumhall.com/C++-CLI%20draft%201.10.pdf
 Signature Ioannis Vranos
http://www23.brinkster.com/noicys
Fred Hebert - 21 Mar 2005 19:09 GMT I found an old program I wrote back in 1991 that still had a hex to binary routine from the old days. It was only 5 lines long, and of course it didn't work in VC.NET, but after 20 minutes I figured out the syntax issues.
Anyhow, I took a look at your example and decided to see how it would work. So I created a new Windows forms .NET project. Added an edit box, a button and a label.
In the OnClick of the button I tried to use your code to convert the hex string "46726564" to it's binary equivalent "Fred" and put it into the label.
First of all I got 12 errors just trying to compile your code starting off with "PCVOID :undeclared identifier", a few syntax errors, some "{ missing function hearer (old-style formal list?)" and other fun things...
I am sure you are a fantastic programmer, but this is exactly what I am talking about. The environment has changed, and the documentation is horrible. I couldn't even find PCVOID in the help index.
I know what I want to do and usually can knock out code pretty quickly. I also usually learn pretty quickly, but it is ridiculous when you have to spent 5 minutes to an hour just trying to find the correct syntax.
Ioannis Vranos - 21 Mar 2005 19:33 GMT > First of all I got 12 errors just trying to compile your code starting off > with "PCVOID :undeclared identifier", a few syntax errors, some "{ missing [quoted text clipped - 7 lines] > also usually learn pretty quickly, but it is ridiculous when you have to > spent 5 minutes to an hour just trying to find the correct syntax. The one that Martin provided was using Win32 facilities and not .NET ones.
Severian - 22 Mar 2005 16:32 GMT >> First of all I got 12 errors just trying to compile your code starting off >> with "PCVOID :undeclared identifier", a few syntax errors, some "{ missing [quoted text clipped - 9 lines] > >The one that Martin provided was using Win32 facilities and not .NET ones. If the OP really is looking for .NET stuff, perhaps he should have a look at Byte.Parse.
-- Sev
Martin Richter [MVP] - 22 Mar 2005 11:02 GMT Hallo Fred!
> First of all I got 12 errors just trying to compile your code starting off > with "PCVOID :undeclared identifier", a few syntax errors, some "{ missing > function hearer (old-style formal list?)" and other fun things... Sorry PCVOID is a define in one of my headers ans is simply a "const void *" PVOID is defined in Win32 and a lot of LPC... but this one is missing so I definedit by myself and didn't include it in the sample.
> I am sure you are a fantastic programmer, but this is exactly what I am > talking about. The environment has changed, and the documentation is > horrible. I couldn't even find PCVOID in the help index. Yes my mistake. Anyhow, the typename itsself should lead you into the correct direction.
> I know what I want to do and usually can knock out code pretty quickly. I > also usually learn pretty quickly, but it is ridiculous when you have to > spent 5 minutes to an hour just trying to find the correct syntax. I am sorry, but what is your problem? To think about the Win32 type syntax? Use your head and a little logic! If LPSTR is a pointer to string and LPCSTR is a const pointer to string? If PVOID is a pointer to void, what could PCVOID be?
Again I am sory that I just cut&paste a code snipplet that wasn't 100% complete. Again: The code sniplet showed a way, its not the bible!
 Signature Martin Richter [MVP] WWJD "In C we had to code our own bugs. In C++ we can inherit them." FAQ : http://www.mpdvc.de Samples: http://www.codeguru.com http://www.codeproject.com
Severian - 18 Mar 2005 19:09 GMT >I am trying to learn VC.NET and convert some Borland C++ applications. The >syntax differences are killing me... [quoted text clipped - 13 lines] >I am hoping that someone can help, because I really don't want to have to >go back to writing all of those little conversion routines. Binary value or binary string?
To convert a value <= ULONG_MAX to an unsigned long binary value:
val = strtoul(strval, NULL, 0); // If strval as 0x1234abcd val = strtoul(strval, NULL, 16); // if strval as 12341bcd
I'm sure there are STL and MFC classes that can do this too.
If you need to convert a hex string to a binary strings, I would use a table For efficiency (sample below), though some languages may provide built-in functions or extra formatting specifications.
Converting from hex to a binary value then to binary text might be faster, but this will handle arbitrarily-long hex and binary values.
Sample ANSI C code:
#include <stdlib.h> #include <string.h> #include <errno.h> #include <ctype.h> #include <stdio.h>
#define TESTING
#undef TRUE #define TRUE 1 #undef FALSE #define FALSE 0
/* Error codes */
#define eDIGIT 1 #define eTRUNC 2 #define eSEPAR 4
static int setdigit(int c, char *binval, int pos);
/* SevStrHexToBin()
Parameters: hexval - Hex value to convert. May be prefixed with h, H, x, X, 0x or 0X. May be suffixed with h, H, x, or X. groupchar - Group digits by this char (0 for no sep) groupchar is also ignored in the input string (groupchar cannot be any hex digit) binval - Where to place the binary string binmaxlen - Size of binval (with room for terminating \0)
Return values: 0 - Success eTRUNC - binval not large enough eDIGIT - invalid hex character in input string eSEPAR - invalid groupchar */
int SevStrHexToBin(const char *hexval, int groupchar, char *binval, int binmaxlen) { static const char hexdig[] = "0123456789abcdef"; int e = 0, pos, c, diglen = groupchar ? 5 : 4; size_t hexlen = strlen(hexval);
memset(binval, 0, binmaxlen); /* In case of error */ if (!hexval || hexlen < 1) return eDIGIT; if (groupchar && strchr(hexdig, tolower((unsigned char)groupchar))) return eSEPAR; if (hexlen >= 2 && hexval[0] == '0' && tolower(hexval[1]) == 'x') hexval += 2; /* Skip 0x if prepended */ else if ( (c = tolower(hexval[0])) == 'x' || c == 'h') hexval++; /* Skip x or h if prepended */ hexlen = strlen(hexval); if (hexlen && (((c = tolower(hexval[hexlen-1])) == 'x') || c == 'h')) hexlen--; /* Ignore trailing "hHxX" */ for (pos = 0; hexlen-- && ((c =*hexval++) != 0); pos += diglen) { if (pos + diglen - (groupchar && (hexlen == 0)) > binmaxlen) return e | eTRUNC; e |= setdigit(c, binval, pos); if (groupchar && hexlen != 0) binval[pos+4] = (char)groupchar; } return e; }
static int setdigit(int c, char *binval, int pos) { static const char errdig[] = "****"; static const char bindig[] = "0000 0001 0010 0011 " /* Spaces for readability */ "0100 0101 0110 0111 " "1000 1001 1010 1011 " "1100 1101 1110 1111 "; int e = 0;
if (c >='0' && c <= '9') memcpy(binval+pos, bindig + 5*(c-'0'), 4); /* Decimal */ else { c = tolower((unsigned char)c); if (c >= 'a' && c <= 'f') memcpy(binval+pos, bindig + 5*(c-'a'+10), 4); /* Alpha */ else { memcpy(binval+pos, errdig, 4); e = eDIGIT; /* Invalid digit */ } } return e; }
#ifdef TESTING
static char *hexbinerrmsg(int e) { switch (e) { case eDIGIT: return " (invalid)"; case eTRUNC: return " (truncated)"; case eDIGIT|eTRUNC: return " (invalid & truncated)"; case eSEPAR: return " (invalid separator)"; default: return ""; } }
int main(int argc, char *argv[]) { char binval[82] = ""; int e = 0;
if (argc < 2) { printf("%s\n", hexbinerrmsg(eDIGIT)); return EXIT_FAILURE; }
/* Simple conversion */
e = SevStrHexToBin(argv[1], 0, binval, sizeof binval); printf("%s: %s%s\n", argv[1], binval, hexbinerrmsg(e));
/* Space separators */
e = SevStrHexToBin(argv[1], ' ', binval, sizeof binval); printf("%s: %s%s\n", argv[1], binval, hexbinerrmsg(e));
/* Colon separators */
e = SevStrHexToBin(argv[1], ':', binval, sizeof binval); printf("%s: %s%s\n", argv[1], binval, hexbinerrmsg(e));
/* Invalid separators */
e = SevStrHexToBin(argv[1], '0', binval, sizeof binval); printf("%s: %s%s\n", argv[1], binval, hexbinerrmsg(e));
return EXIT_SUCCESS; }
#endif
-- Sev
Fred Hebert - 21 Mar 2005 23:04 GMT To keep it simple, the basic question was, or should have been:
Aren't there built in functions for simple things like this?
The correct answer is "NO, you have to do it the hard way".
Here's my quick and dirty solution:
#define hextobin(c) ((c)>='a'&&(c)<='f' ? (c)-'a'+10 : (c)>='A'&&(c)<='F' ? (c)-'A'+10 : (c)-'0')
...
char BinKey[16]; for(int i=0; i < textBox1->Text->Length; i=i+2) { BinKey[i>>1] = (unsigned int)(hextobin(textBox1->Text->get_Chars(i)) << 4) + hextobin(textBox1->Text->get_Chars(i+ 1)); }
The input has been previously validated. Again, in my old environment this was done with a hex mask edit component that validated the length, took out the dashes, converted the case. Basically no code. Then 1 line to convert to binary.
After spending 30 minutes adding the missing functionality of the mask edit, which I thought should already be there, I just wanted to convert it to binary. I thought surely this basic function is built in? I mean the hex mask edit didn't show up until 1999, I could understand something that "advanced" being missing, but...
I ask again, is everything this difficult?
Severian - 22 Mar 2005 02:18 GMT >To keep it simple, the basic question was, or should have been: > [quoted text clipped - 30 lines] > >I ask again, is everything this difficult? Well I don't think it was entirely clear what you wanted. It noew appears you want to create some kind of binary *value* of 16 bytes from 32 hex characters. My code provided binary *text* from hex *text*, of arbitrary length with error checking.
The task I assume you're looking for (to convert a max of 32 bytes of hex to 16 bytes of binary) is doable several simple ways:
/* C; Assumes hex digits always valid, in pairs and little-endian */
void hex32tobin16(char *hex, unsigned char *binkey) { int i; memset(binkey, 0, 16); char digs[]="0123456789abcdef"; for (i=0; i<16 && hex[i*2]; i++) binkey[i] = strchr(digs, tolower(hex[i*2]))<<4 + strchr(digs, tolower(hex[i*2+1]));
/* C; Assumes hex digits always valid, in pairs */
void hex32tobin16(char *hex, unsigned char *binkey) { int v, i, j; memset(binkey, 0, 16); for (i=0, j=0; i<32 && hex[i]; i+=2) { sscanf(hex+i, "%2x", &v); binkey[j++] = (unsigned char)v; } }
/* C; Assumes hex digits always valid, in pairs, little-endian */ /* Also assumes ASCII order (0-9...A-F...a-f) */
#define xtob(c) (((c)<=9)?((c)-'0'):(((c)<='F')?((c)-'A'):((c)-'a'))); void hex32tobin16(char *hex, unsigned char *binkey) { int i memset(binkey, 0, 16); for (i=0; i<32; i+=2) binkey[i>>1] = (xtob(hex[i]) << 4) + xtob(hex[i+1]); }
-- Sev
Severian - 22 Mar 2005 16:05 GMT >>To keep it simple, the basic question was, or should have been: >> [quoted text clipped - 47 lines] > char digs[]="0123456789abcdef"; > for (i=0; i<16 && hex[i*2]; i++)
> binkey[i] = strchr(digs, tolower(hex[i*2]))<<4 + > strchr(digs, tolower(hex[i*2+1])); ^ I forgot parens here v
> binkey[i] = (strchr(digs, tolower(hex[i*2]))<<4) + > strchr(digs, tolower(hex[i*2+1])); [quoted text clipped - 16 lines] > >#define xtob(c) (((c)<=9)?((c)-'0'):(((c)<='F')?((c)-'A'):((c)-'a'))); ^ Forgot +10 here v
>#define xtob(c) (((c)<=9)?((c)-'0'):((((c)<='F')?((c)-'A'):((c)-'a'))+10));
>void hex32tobin16(char *hex, unsigned char *binkey) >{ [quoted text clipped - 3 lines] > binkey[i>>1] = (xtob(hex[i]) << 4) + xtob(hex[i+1]); >} Sorry, I was sleepy.
Here's my favorite, that makes damn nearly every assumption about the architecture possible, and assumes hexkey is always exacly 32 characters. It is horrible code:
#define hex32tobin16(h,b) \ (sscanf((h),"%4x%4x%4x%4x".(b),(b)+4,(b)+8,(b)+12)
I'm not quite sure why you think there should be some built-in function to convert 32-byte hex valies to 16 binary bytes?
-- Sev
Fred Hebert - 23 Mar 2005 17:57 GMT > I'm not quite sure why you think there should be some built-in > function to convert 32-byte hex valies to 16 binary bytes? > > -- > Sev This thing has really gotten blown out of proportion, but...
The reason I think this should be a standard function is that it is a very common function in my world. Converting arbitrary length hex strings to their binary equivalent and back is something I do ever day. Wether it's an encryption key, 80 char line of code in a Motorola S file, checksum from a serial communications session, hex dump for the e-prom programmer, etc.
Yes the checksum is usually a 16 bit or 32 bit integer, so why use HexToBin? Well it is also usually not an Intel integer and the normal integer conversions don't work.
By the way, I found a similar function that is supposed to be part of some "security" library, but the docks are fuzzy and it doesn't appear to be installed on my system.
This is just one example. In my "standard library" of string handling routines I am used to having hundreds of formatting and conversion routines. Now I find myself rewriting InitialCaps routines. One of my programmers who I asked to help with some of this got frustrated and actually derived his own "String" class. I think that was a bad idea. It did solve an immediate problem, but I can see it biting us big time later. Also I think he just copied some of the Borland source because he's just not that fast, so I told him to get rid of it...
Please don't take my comments personally (unless you are the one at Microsoft who decided to not include these routines, or created the help text). I appreciate the help and code fragments. They were useful if only to see a .NET approach to the problem.
My comment about "probably an excellent programmer" was sincere, and I was able to deduce what was meant, even with a few typos. Do you think I have never made a typo?
I guess it is really hard to appreciate my perspective, if you don't write the type of programs I write, and have never used these other environments. Before .NET we had cross platform Windows/Linux, and mixed language GNU C++, Borland C++ and Borland Delphi, Borland Kylix. There are annoying things in my environment too, but I guess I am just used to them.
If we wish to transition to .NET it is going to be difficult, and I am really surprised at how many things are missing from what I think should be the standard library. The other thing I am surprised about is poor performance. This may not be noticeable to the typical user, but when you are talking to devices and millisecond timing is important it is an issue.
As I stated in one of my other messages .NET may not be right for us. I looked at the standard MSC/MFC and it is worse as far as trying to convert existing code.
Before this experience I thought that the differences between Microsoft and Borland were more like the differences between Ford and Chevrolet. That is 6 of one or half a dozen of the other, and it mostly came down to user preference. Now I see the difference is much more dramatic.
I have been using the Delphi .NET stuff to try to become more familiar with the environment. This is helping, but for most of the .NET stuff they just use the Microsoft help, which I think is the biggest problem.
I mean it would be a lot easier with better docs. I have ordered a few books suggested by others and am hoping this will also help.
In final summation, IMHO:
- The documentation sucks. - A lot of basic functions are missing. I am digging up my old code and creating our own addendum to the standard library just like in the old days. - I will eventually become accustomed to the syntax. - I will survive...
Tim Robinson - 23 Mar 2005 23:45 GMT > In final summation, IMHO: > > - The documentation sucks. Agreed. However, Microsoft Visual C++ (mostly) conforms to the C++ standard, so plenty of other people have written better documentation.
> - A lot of basic functions are missing. I am digging up my old code and > creating our own addendum to the standard library just like in the old > days. Your standard library != The Standard Library.
> - I will eventually become accustomed to the syntax. > - I will survive... You've been spoiled on Borland C++. They included a stack of non-standard functions. VC++ basically conforms to the C++ standard, and includes a couple of non-standard functions (their names start with an _). However, when moving to a new compiler, you can't assume the existence of anything except the C++ Standard Library.
HexToBin is very much a non-standard, Borland-Special function. If you want that, stick to Borland. If you want to move compilers, then feel free to, but don't assume you'll retain anything that's not standard.
 Signature Tim Robinson MVP, Windows SDK
Fred Hebert - 24 Mar 2005 23:27 GMT Tim,
You are right I just got used to the common library in all of the different Borland products and GNU compiler we are using. I have already recreated most of the "missing" stuff. My blood pressure is starting to come down and I am feeling a little better already. :-)
Anyhow, you sound like you are fairly sharp. I have a problem with this program I am converting. Of the thousands of lines of code I have one problem that I thought would be simple, but is giving me fits.
I am trying to use a Win32 DLL in a .NET application. The DLL encapsulates the interface to some external hardware and has many exported functions, but I am having problems with only 1. The function requires the handle of a windows form and I can't seem to get it to work.
I created the simplest project I could to demonstrate the problem if you can spend 5 minutes cutting pasting I would greatly appreciate it:
1. Create a new VC.NET Windows Forms Application.
2. Drop 4 TextBox controls and a Button on the form. [textBox1] [textBox2] [textBox3] [textBox4] [button1] 3. Edit the properties of the text controls like this: [textBox1] Name: IpEdit Text: 10.1.1.1 [textBox2] Name: PortEdit Text: 1234 [textBox3] Name: TimeoutEdit Text: 10 [textBox4] Name: KeyEdit Text: fffffffffffffffffffffffffffffff << should be 32 f's
4. Double Click on the button, and enter the following code: --------------------------------------- unsigned char BinKey[16]; // key is entered in HEX but must be converted to binary value for use for(int i=0; i < KeyEdit->Text->Length; i=i+2) { BinKey[i>>1] = (unsigned int)(hextobin(KeyEdit-> Text->get_Chars(i)) << 4) + hextobin(KeyEdit->Text->get_Chars(i+1)); } OmniConnect(IpEdit->Text, PortEdit->Text->ToInt32, TimeoutEdit->Text->ToInt32, BinKey, Handle); ---------------------------------------
5. The the beginning of the Form1.h, just after the "#pragma once" line add the following lines: --------------------------------------- #include <windows.h> #define hextobin(c) ((c)>='a'&&(c)<='f' ? (c)-'a'+10 : (c)>='A'&&(c) <='F' ? (c)-'A'+10 : (c)-'0') // define function types for the exported functions in the DLL typedef int (_stdcall *pOmniConnect) (char * IpAddress, unsigned int Port, unsigned int Timeout, unsigned char EncryptionKey[16], HWND NotifyWindow); // declare function variables for the exported functions in the DLL pOmniConnect OmniConnect; ---------------------------------------
Now I know I left out the OnCreate of the form where the DLL is loaded and all of the other DLL exports, but I think I have everything you need to compile, that is once the "Handle" issue is resolved.
Of course it won't run but right now I am just trying to get past this one problem. In the real program, if I comment out the code in the button click the rest of the program runs fine. I didn't have problems with any of the functions, but most of them just pass strings and integers.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|