as per title, i couldnt find another tutorial on this...
i found a piece of code here: http://classroomm.com/objective-c/index.php?action=printpage;topic=2891.0
but it is giving me alot of warnings and doesnt really know how to use it.
Any other solution?
You might want to check this out - http://code.google.com/p/ofc/wiki/DCRC32
Just use crc32() function, it's simple and straight forward. See this answer for details: https://stackoverflow.com/a/14533955/1760595
I modified http://www.csbruce.com/software/crc32.c slightly,
and used UTF8String method to get a pointer to the internal CString representation of NSString.
This saves copying.
Unfotunately zlib's crc32 implementation needs a buffer length.
This one just terminates with the 0 byte at the end of the C-String.
#implementation NSString (crc32)
static unsigned long Crc32_String(const char *string)
{
static const unsigned long crcTable[256] = {
0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,
0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,
0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,
0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,
0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,
0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC,
0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,
0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,
0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,
0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,
0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,
0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE,
0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,
0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,
0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,
0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,
0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268,
0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,
0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,
0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,
0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,
0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,
0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,
0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,
0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,
0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,
0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,
0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,
0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D };
unsigned long crc32;
unsigned char *byteBuf;
size_t i;
char byte;
/** accumulate crc32 for buffer **/
crc32 = 0;
byteBuf = (unsigned char *) string;
i = 0;
while ((byte = byteBuf[i++])) {
crc32 = (crc32 >> 8) ^ crcTable[ (crc32 ^ byte) & 0xFF ];
}
return( crc32 ^ 0xFFFFFFFF );
}
- (unsigned long)crc32
{
return Crc32_String(0, [self UTF8String]);
}
#end
I've written a C++/CLI wrapper for a C++-DLL to use this DLL in a C# programm.
However, when I call a function, which takes a char* I get a AccessViolation
int Wrapper::Net_methodX(int a, String^ key, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(key);
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
int val = methodX(a,cKey, v); // AccessViolation here
Marshal::FreeHGlobal(ptr);
return val;
}
The signature of the C++-function is
int methodX(int a, char *Key, long v);
EDIT 1
Just to "pin" like the following didn't work either:
int Wrapper::Net_methodX(int a, String^ key, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(key);
char* cKey = static_cast<char*>(ptr.ToPointer());
pin_ptr<char> pinned = cKey;
int val = methodX(a,cKey, v);
Marshal::FreeHGlobal(ptr);
return val;
}
EDIT 1 END
EDIT 2
I tried also PtrToStringChars the following way (Thanks Matt, found also some doc here):
int Wrapper::Net_methodX(int a, String^ key, long v)
{
pin_ptr<const wchar_t> wkey = PtrToStringChars(key);
size_t convertedChars = 0;
size_t sizeInBytes = ((key->Length + 1) * 2);
errno_t err = 0;
char * ckey = (char * ) malloc(sizeInBytes);
err = wcstombs_s(&convertedChars, ckey, sizeInBytes, wkey, sizeInBytes);
int val = methodX(A_Symbol_Table,ckey, Value);
return val;
}
AccessViolation still occurs, maybe it's an error in methodX() (which is a Third-party-DLL).
EDIT 2 END
I have read some related questions here, but did not find a solution yet.
Any hints?
Thank you.
I know this is an old question, but for anyone who stumble upon this question looking for an answer, here are some simpler solutions.
Simply use sprintf to do the conversion like this: sprintf(cStr, "%s", clrString);. See my answer to this question for a complete example.
Read KB311259 as suggested by Matt Smith. If you are using VS 2008 or higher, use marshal_as<> (Method #4 in the KB). It's much simpler than the other methods in that document.
Simon,
I tried out your example and I do not get an Access Violation. Here's my code:
using namespace System;
using namespace System::Runtime::InteropServices;
ref class Wrapper
{
public:
static int Net_methodX(int a, String^ key, long v);
};
int methodX(int a, char * pKey, long v)
{
IntPtr ptr = static_cast<IntPtr>(pKey);
String ^ pString = Marshal::PtrToStringAnsi(ptr);
System::Console::WriteLine(pString);
return a;
}
int Wrapper::Net_methodX(int a, String^ pKey, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(pKey);
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
int val = methodX(a,cKey, v); // AccessViolation here
Marshal::FreeHGlobal(ptr);
return val;
}
void main()
{
Wrapper wrapper;
String ^ p = gcnew String("Hello");
wrapper.Net_methodX(0, p, 0);
}
Also, I have a few comments:
Read here: http://support.microsoft.com/kb/311259
You are using a pin_ptr to native memory. The StringToHGlobalAnsi method returns native memory, so I don't think using a pin_ptr makes sense here. A pin_ptr would make sense if you were using a method that gives you back a pointer to managed memory (like PtrToStringChars). Unless you are modifying the string, you probably want to go with the PtrToStringChars approach anyways--to avoid unnecessary allocation and copying.
Would you post an example version of methodX that causes the problem? If I can reproduce the issue, I might be able to be more helpful.
Simon
I think there is a problem with the following code
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
You might want to read this http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/0bd049fe-844a-4cb6-b9f6-c8f5107bc957
Let me know if it helped you.
Sujay