【发布时间】:2015-06-10 12:10:45
【问题描述】:
在打开主题之前搜索了更多为我服务的回复,我的错误仍然存在,在 Delphi XE6 64x 中创建了一个 dll,如下所示:
function GeraChave(Action : PAnsiChar; StrCrip : PAnsiChar; Cnpj : PAnsiChar; idPC: PAnsiChar): PAnsiChar; stdcall;
var
KeyLen : Integer;
KeyPos : Integer;
OffSet : Integer;
Dest, Key : String;
SrcPos : Integer;
SrcAsc : Integer;
TmpSrcAsc : Integer;
Range, I : Integer;
matKey : Array[0..7] of String;
begin
if (StrCrip = '') Then
begin
Result:= '';
Exit;
end;
for I := 0 to 8 do
matKey[I] := Copy(idPC, I, 1);
Key := 'A#%tgNh*'+ matKey[0] +'UJklo'+ matKey[1] + 'O' + cnpj + 'O' +
'798DS'+ matKey[2] +'Cea'+ matKey[3] +'SEc%7*I'+ matKey[4] +'u@Ed#'+
matKey[5] +'f$f'+ matKey[6] +'%g&j-9'+ matKey[7] +'sc';
Dest := '';
KeyLen := Length(Key);
KeyPos := 0;
SrcPos := 0;
SrcAsc := 0;
Range := 256;
if (Action = UpperCase('C')) then
begin
Randomize;
OffSet := Random(Range);
Dest := Format('%1.2x',[OffSet]);
for SrcPos := 1 to Length(StrCrip) do
begin
SrcAsc := (Ord(StrCrip[SrcPos]) + OffSet) Mod 255;
if KeyPos < KeyLen then KeyPos := KeyPos + 1 else KeyPos := 1;
SrcAsc := SrcAsc Xor Ord(Key[KeyPos]);
Dest := Dest + Format('%1.2x',[SrcAsc]);
OffSet := SrcAsc;
end;
end
Else if (Action = UpperCase('D')) then
begin
OffSet := StrToInt('$' + copy(StrCrip,1,2));
SrcPos := 3;
repeat
SrcAsc := StrToInt('$' + copy(StrCrip,SrcPos,2));
if (KeyPos < KeyLen) Then KeyPos := KeyPos + 1 else KeyPos := 1;
TmpSrcAsc := SrcAsc Xor Ord(Key[KeyPos]);
if TmpSrcAsc <= OffSet then TmpSrcAsc := 255 + TmpSrcAsc - OffSet
else TmpSrcAsc := TmpSrcAsc - OffSet;
Dest := Dest + Chr(TmpSrcAsc);
OffSet := SrcAsc;
SrcPos := SrcPos + 2;
until (SrcPos >= Length(StrCrip));
end;
Result := PAnsiChar(Dest);
end;
Exports
GeraChave;
begin
end.
我的 C# .NET 代码如下所示:
public partial class _Default : System.Web.UI.Page
{
[DllImport(@"H:\FTP\HOME\Web\testes\dllDelphi\Bin\DllChave.dll",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern string GeraChave(string xAction, string StrCrip, string Cnpj, string idPC);
protected void Page_Load(object sender, EventArgs e)
{
string str = "A75BD3FD" + "|15/12/2016|" + "04564521020004";
string xTp = "C";
string Cnpj = "04564521020004";
string IDPC = "A75BD3FD";
string xRes = "";
xRes = GeraChave(xTp, str, Cnpj, IDPC);
}
}
当我调用 DLL 时出现错误“用户代码未处理 BadImageFormatException”
谢谢!
【问题讨论】:
-
"结果 := PAnsiChar(Dest);" - 这不会转换任何东西。你应该像
Result := PAnsiChar(AnsiString(Dest));那样做,但即便如此,问题是谁以及何时从你刚刚分配的字符串中释放堆内存? C# 无法访问 Delphi 堆,我也没有看到您将 Delphi 堆管理器切换到某些库存窗口低堆。所以我认为这是另一条探索路线,我一般如何将字符串从 Delphi 函数返回到 C# -
看起来你错过了抑制名称修改 - msdn.microsoft.com/en-us/library/… 使用 CFF Explorer 检查你的函数从 DLL 导出的确切名称是什么?
-
@Arioch'The Nope。这导致
EntryPointNotFoundException。无论如何,双方都没有进行任何名称修改。这不是 C++。 -
大卫,DllImport 中有 win32/win64 开关吗?我认为 .Net 程序集与 CPU 无关,因此它们不能是 x86 或 x64 ///
char*==PAnsiChar的返回值似乎必须是 StringBuilrder,而不是字符串! msdn.microsoft.com/en-us/library/aa984739(v=vs.71).aspx -
@Arioch ExactSpelling 抑制了这一点。但无论如何,如果未找到 A 或 W 变体,则会尝试确切的名称。