#c# #delphi
#c# #delphi
Вопрос:
Я написал функцию для шифрования строки в Delphi 10. Все работает нормально, у меня есть такая же функция в Winform, и результат отображается в поле Memo, однако, когда я вызываю функцию из C #, я получаю сообщение об ошибке, когда я запускаю эту функцию шифрования вызова из C #, я получаю «Параметр не найден», который является результатом исключения в Delphi.
Кто-нибудь может здесь помочь?
function Encrypt(str: PWideChar; len: Integer): Boolean; stdcall;
begin
try
eString := AES128_Encrypt('Test','TestPassword');
PwValue := PWideChar(eString);
StrLCopy(str, PwValue, len);
Result := true;
except
On E: Exception do
begin
PwValue := PWideChar(E.Message);
StrLCopy(str, PwValue, len);
end;
end;
end;
function AES128_Encrypt(Value, Password: string): string; stdcall;
var
hCProv: HCRYPTPROV;
hKey: HCRYPTKEY;
lul_datalen: Integer;
lul_buflen: Integer;
Buffer: TBytes;
begin
Assert(Password <> '');
if (Value = '') then
Result := ''
else begin
hCProv := __CryptAcquireContext(PROV_RSA_AES);
try
hKey := __AES128_DeriveKeyFromPassword(hCProv, Password);
try
// allocate buffer space
lul_datalen := Length(Value) * SizeOf(Char);
Buffer := TEncoding.Unicode.GetBytes(Value ' ');
lul_buflen := Length(Buffer);
// encrypt to buffer
Win32Check(CryptEncrypt(hKey, 0, True, 0, @Buffer[0], lul_datalen, lul_buflen));
SetLength(Buffer, lul_datalen);
// base 64 result
Result := Base64_Encode(Buffer);
finally
CryptDestroyKey(hKey);
end;
finally
CryptReleaseContext(hCProv, 0);
end;
end;
end;
Вызывая его как
eString := AES128_Encrypt('ii', 'o3ew232we22o');
Код на C #
[DllImport(@"<Path of dll>", EntryPoint = "Enrypt", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern bool Enrypt(StringBuilder sb, int len);
public static string Encrypt()
{
try
{
StringBuilder str = new StringBuilder(256);
System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.STA);
bool result = Encrypt(str, str.Capacity);
if (result)
{
return str.ToString();
}
}
catch (Exception ex1)
{
MessageBox.Show(ex1.ToString());
}
return "";
}
Комментарии:
1. где находится код c #?
2. опубликовал полный код
3. 2 замечания, 1) отметьте вашу процедуру шифрования delphi как stdcall, если вы не укажете соглашение о вызове, по умолчанию это будет cdecl. 2) Используйте Widestring на стороне delphi и маршалируйте как BSTR на C #. Pwidechar и stringbuilder несовместимы
4. Я пометил функцию как stdcall (пожалуйста, смотрите Обновленный код). Я не получаю второй комментарий. Если я заменю свой AES128_Encrypt (‘Test’, ‘TestPassword’) на ‘некоторый мусор, который я хотел вернуть’, он просто отлично работает
5. Pwidechar Delphi не может быть маршалирован как конструктор строк c #, это так просто.