1

My goal is to get this:

BYTE       Data1[]     = {0x6b,0x65,0x79};
BYTE       Data2[]     = {0x6D,0x65,0x73,0x73,0x61,0x67,0x65};

But my starting point is:

std::string msg = "message";
std::string key = "key";

I am not able to get from std::string to BYTE[].

I tried the following:

std::vector<BYTE> msgbytebuffer(msg.begin(), msg.end());
BYTE*       Data1     = &msgbytebuffer[0];

This didn't cause compile or run time error. However, the end result (I feed this to a winapi function - crypto api) was not the same as when I used the actual byte array like in top most ({0x6D,0x65,0x73,0x73,0x61,0x67,0x65}).

halfer
  • 19,824
  • 17
  • 99
  • 186
Noitidart
  • 35,443
  • 37
  • 154
  • 323
  • 1
    what about `std::string::c_str()` returning `const char*`? – Quest Dec 29 '16 at 16:22
  • Thanks Quest for the suggestion, I am very new to writing C++, may you please give me a snippet/demo. – Noitidart Dec 29 '16 at 16:23
  • 1
    In what way was it different? – Yakk - Adam Nevraumont Dec 29 '16 at 16:26
  • 1
    Thats because `std::string` has a null terminator (`\0`) and the vector of byte (`std::vector`) does not? So winapi is misbehaving? – Amadeus Dec 29 '16 at 16:28
  • What exactly is meant with `BYTE` ? AFAIK there's no `BYTE` data type in c++ – clickMe Dec 29 '16 at 16:29
  • @yakk the end result of the crypto api with the top most is `4a 52 c3 c0 ab c0 a0 60 49 d1 ab 64 8b b4 05 7e 3f f5 f3 59` but when I use my vector method, the end result is `03 54 c0 02 d9 8b c2 83 b7 7b af f0 3b c9 76 00 63 00 dc 76`. – Noitidart Dec 29 '16 at 16:29
  • Ah thanks @Amadeus - I tried to create the vector without the null terminator like this: `std::vector msgbytebuffer(msg.begin(), msg.end()-1)` - I put a `-1` after `msg.end()` but it didnt result in same result as when using hard coded byte array. – Noitidart Dec 29 '16 at 16:31
  • @SebTu I think it is a `unsigned char`. Per the docs of `typedef unsigned char BYTE;` – Noitidart Dec 29 '16 at 16:32
  • @Amadeus thanks! I don't understand :( May you please show me snippet, I apologize I'm real new to writing this stuff. – Noitidart Dec 29 '16 at 16:34
  • @Amadeus The `begin()` `end()` range of a `std::string` doesn't include the null terminator unless you really work at it. – Yakk - Adam Nevraumont Dec 29 '16 at 21:51
  • @Noitidart No, not after the crypto API. I mean compare `Data1` via `std::string` with `Data1` via `[] = { blah }` in the debugger. How do they differ? – Yakk - Adam Nevraumont Dec 29 '16 at 21:52
  • @Yakk that was to be meant in the comment. The lack of `\0` could be causing the misbehaviour of the winapi – Amadeus Dec 29 '16 at 21:59
  • 1
    I don't understand why you opted for an answer that give you null terminator. You don't need it. What encoding do you want to use for the text? – David Heffernan Dec 30 '16 at 09:37
  • @DavidHeffernan I accepted it because I learned a lot from it. The actual problem with the code was, before when I was using an array `BYTE Data1[] = {...}` then doing `sizeof(Data1)` would correctly give me its size. But after I switched to `BYTE *Data1`, doing `sizof(Data1)` was no longer the actual size, but just size of a pointer, so 4 or 8 bytes. – Noitidart Dec 30 '16 at 14:21
  • 1
    The code in the question looks better than using c_str. You know the lengtg of the vector. Don't misuse sizeof. You could even use `&msg[0]` with a cast and avoid any allocation and copying. – David Heffernan Dec 30 '16 at 14:26
  • Thanks @DavidHeffernan - may you please post a snippet of the cast to avoid allocation and copying. I am new to writing/thinking C++, it would really help me out! – Noitidart Dec 30 '16 at 15:00
  • 1
    `static_cast(&msg[0])` – David Heffernan Dec 30 '16 at 15:35
  • Ah thanks @DavidHeffernan! Will test right now! So to recap - I am going to test `BYTE Data1[] = static_cast(&msg[0])` and `sizeof(Data1)` will now give me length? – Noitidart Dec 30 '16 at 15:38
  • 1
    No, that's not right. Pass `static_cast(&msg[0])` to whatever expects a `BYTE*` and for the length use `msg.length()`. This means you will pass the data in whatever encoding it is stored in. Do you know what encoding is used? Is it ANSI? – David Heffernan Dec 30 '16 at 15:40
  • 1
    `BYTE Data1[] = ...` requires the rhs to be a constant, and a `BYTE*` that is only known at runtime is certainly not that. You can't expect to use `sizeof(...)` with something that is dynamic. – David Heffernan Dec 30 '16 at 15:41
  • Ah thanks for the quick answer! I seriously appreciate this! I'm moving away from ctypes to actual C and C++ now haha. The encoding is Unicode, I am working on this snippet here - http://stackoverflow.com/q/41384395/1828637 – Noitidart Dec 30 '16 at 15:42
  • Unicode is not an encoding. Do you mean UTF8 or UTF16 or something else. Only UTF8 makes sense in a std::string – David Heffernan Dec 30 '16 at 15:58

2 Answers2

2

You can use string::c_str() function which returns a pointer to c style string that can be passed to winapi functions like:

foo(string.c_str());

What it actually does is that it returns a pointer to an array that contains a null-terminated sequence of characters.


I suppose BYTE[] is actually a char array. You can assign your std::string to char array by doing:

std::string str = "hello";
BYTE byte[6];   // null terminated string;
strcpy(byte, str.c_str());  // copy from str to byte[]

If you want to copy the str without the 0 at the end, use strncpy instead:

BYTE byte[5];
strncpy(byte, str.c_str(), str.length());
Pang
  • 9,564
  • 146
  • 81
  • 122
Quest
  • 2,764
  • 1
  • 22
  • 44
  • Ah thanks Quest, but I need to set it to BYTE[] as I use it in multiple places. But up vote for your time! – Noitidart Dec 29 '16 at 16:27
  • Ah thanks for that update! May you please show how to get it without the null terminator of the string. Excuse me please, I'm an extreme newbie. – Noitidart Dec 29 '16 at 16:33
  • 1
    I've updated it again. If it solved your problem don't forget to mark the answer as accepted please. – Quest Dec 29 '16 at 16:39
  • Thank you @Quest! This is very cool I learned a lot. My problem is still there but I think you answered the question. So I accepted it. Thank you sir! My current problem is now I'm not able to do `BYTE byte[msg.size()]`, its saying I have to allocate if I want a dynamic size like that. Weirdness. – Noitidart Dec 29 '16 at 16:42
  • 1
    @Noitidart use `BYTE* byte = (BYTE*)malloc(msg.size());` but don't forget to call `free(byte);` at the end of your program. – Quest Dec 29 '16 at 16:45
  • @Quest, The hyperlink to strcpy has a typo. It should be 'strncpy' rather than 'strncmp'. – Praneeth Kumar Gunda Feb 28 '18 at 05:13
1

Seems me that winapi is waiting a null terminated c-string. You can achieve that by using:

msg.c_str();

or, using your BYTE type, something like that:

std::vector<BYTE> msgbytebuffer(msg.length() + 1, 0);
std::copy(msg.begin(), msg.end(), msgbytebuffer.begin());
Amadeus
  • 10,199
  • 3
  • 25
  • 31