std::string
и std::wstring
нельзя скопировать друг на друга с помощью std::copy
и связанных с ними методов, за исключением случаев, когда источник содержит символы ASCII.Это не тот случай, здесь.Несмотря на то, что вы смотрите на ASCII, зашифрованный текст будет в двоичном виде, это не ASCII и не Unicode.
Вы можете скопировать std::wstring
в двоичном виде в std::string
.Но я думаю, что это вам здесь не поможет, потому что encrypt
, похоже, ожидает нулевую строку.
Вместо этого вы можете конвертировать UTF16 в UTF8 и обратно:
#include <string>
#include <codecvt>
extern "C" __declspec(dllexport)
bool aes_crypter(const wchar_t* string_in, BYTE* data, int &datalen)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
std::string utf8 = convert.to_bytes(string_in);
std::string encr = encrypt(utf8, X_KEY, X_PSS);
datalen = encr.size();
if(datalen > 4096)
return false;
memcpy(data, &encr[0], datalen);
return true;
}
extern "C" __declspec(dllexport)
void aes_decrypter(const BYTE *data, int datalen, wchar_t* string_out)
{
std::string utf8 = decrypt(data, datalen, X_KEY, X_PSS);
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
std::wstring utf16 = convert.from_bytes(utf8);
wcscpy_s(string_out, 4096, utf16.c_str());
}
Ваш C #Приложение получит зашифрованный двоичный файл data
, некоторой длины datalen
["simpleAES.dll",
CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private static extern bool aes_crypter(string input, IntPtr data, ref int datalen);
["simpleAES.dll",
CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private static extern bool aes_decrypter(IntPtr data, int datalen, StringBuilder sb);
static void Main(string[] args)
{
int datalen = 0;
IntPtr data = Marshal.AllocHGlobal(4096);
if (aes_crypter("1234", data, ref datalen))
{
StringBuilder sb = new StringBuilder(4096);
aes_decrypter(data, datalen, sb);
string recover = sb.ToString();
Console.WriteLine(recover);
}
Marshal.FreeHGlobal(data);
}
Вы также должны передать размер для StringBuilder
вместо того, чтобы предполагать, что это 4096
Обратите внимание, чтов C ++ метод c_str()
ищет символ NUL
и пытается вернуть строку с нулевым символом в конце.Но ваша функция шифрования создает двоичные данные, которые могут иметь много нулей в середине.
Вы можете упростить ситуацию, если функция шифрования принимает двоичный ввод и выводит std::vector<BYTE>
вместо std::string
.Пример
std::vector<BYTE> encrypt(binary_data_to_encrypt, datalen, X_KEY, X_PSS);