我正在尝试将一个加密函数从我们的遗留代码中分离到一个dll中,我可以从C#中调用这个dll,但是我在使它正常工作时遇到了问题,并且在调用dll时一直存在访问冲突。
我不知道AV在哪里发生,因为delphi在dll附加到另一个进程时很难击中我的断点。
我昨天用大卫·赫弗南( David )的答案-- 在64位中将delphi中的字符串返回给C#调用方 --让它工作了,但我的成功是短暂的,因为我把字符串参数改成了普通的string
's (delphi),发现它不起作用,并将它们改为AnsiString
(我们的加密程序期望Ansi)。因为我改变了这些param类型,我一直没能让它再次工作。
这是我的Delphi代码:
procedure Encrypt(const Source: AnsiString; const Key: AnsiString; var OutPut:PAnsiChar; const OutputLength: Integer);
var
EncryptedString, EncodedString: AnsiString;
begin
EncryptedString := Crypt(Source, Key);
EncodedString := Encode(EncryptedString);
if Length(EncodedString) <= OutputLength then
System.AnsiStrings.StrPCopy(Output, EncodedString);
end;
exports
Encrypt;
我的C#来电者:
[DllImport("AsmEncrypt.dll", CharSet = CharSet.Ansi)]
public static extern void Encrypt(string password, string key, StringBuilder output, int outputlength);
// using like this:
Encrypt(credentials.Password, myKey, str, str.Capacity);
我现在最好的选择是,我已经忽略了dll的一些参数,因为它似乎在到达OutputDebugStr()
之前就崩溃了,我把dll放在了Encrypt()
的第一行
我们将非常感谢所有的帮助。
发布于 2021-10-13 11:02:24
将Delphi函数更改为
procedure Encrypt(Source, Key, OutPut: PAnsiChar; OutputLength: Integer); stdcall;
才能让这个代码正常工作。
您可能还应该设置长度参数IN/OUT,以便调用方能够在调用返回时调整字符串生成器对象的大小。这也将允许被调用方向调用方发出任何错误信号,这是当前设计中的另一个缺陷。
我还必须说,使用AnsiString
作为字节数组会导致失败。该是你开始加密的时候了。如果您有文本,然后将其编码为具有特定编码的字节数组,通常这意味着UTF-8。然后将该字节数组加密为另一个字节数组。
发布于 2021-10-13 09:03:54
来自此文档页
AnsiString结构包含一个32位长度指示器、一个32位参考计数、一个16位数据长度,指示每个字符的字节数,以及一个16位代码页。
因此,AnsiString
不仅仅是一个指向一个字符数组的指针--它是一个指向一种特殊结构的指针,它编码了一组信息。
但是,.NET的P/Invoke机器将传递一个指向字符数组的指针。德尔福将尝试将其解释为指向其特殊AnsiString结构的指针,而事情不会顺利进行。
我认为您将很难在互操作中使用AnsiString
。最好选择一个.NET和Delphi都知道的字符串类型。如果您需要将其转换为AnsiString
,请在德尔菲中这样做。
https://stackoverflow.com/questions/69552512
复制相似问题