我有一个遗留加密pas文件,我想编译成一个DLL,我可以从C#应用程序调用。
我对Delphi一无所知并且正在使用Delphi XE2。
我正在尝试导出过程StringHashSHA1。
尝试构建DLL时,我得到以下错误:
我看不出我哪里出错了。 如何将以下代码编译为dll?
library encrypt;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
ShareMem,
System.SysUtils,
System.Classes,
Windows,
System.Types;
// LbUtils;
{$R *.res}
{ message digest blocks }
type
TMD5Digest = array [0..15] of Byte; { 128 bits - MD5 }
TSHA1Digest = array [0..19] of Byte; { 160 bits - SHA-1 }
{ message digest context types }
type
TLMDContext = array [0..279] of Byte; { LockBox message digest }
TMD5Context = array [0..87] of Byte; { MD5 }
TSHA1Context = record { SHA-1 }
sdHi : DWord;
sdLo : DWord;
sdIndex : DWord;
sdHash : array [0..4] of DWord;
sdBuf : array [0..63] of Byte;
end;
{ SHA-1 constants }
const
{ 5 magic numbers }
SHA1_A = DWORD( $67452301 );
SHA1_B = DWORD( $EFCDAB89 );
SHA1_C = DWORD( $98BADCFE );
SHA1_D = DWORD( $10325476 );
SHA1_E = DWORD( $C3D2E1F0 );
{ four rounds consts }
SHA1_K1 = DWORD( $5A827999 );
SHA1_K2 = DWORD( $6ED9EBA1 );
SHA1_K3 = DWORD( $8F1BBCDC );
SHA1_K4 = DWORD( $CA62C1D6 );
{ Maskes used in byte swap }
LBMASK_HI = DWORD( $FF0000 );
LBMASK_LO = DWORD( $FF00 );
{ SHA-1 message digest }
procedure InitSHA1(var Context: TSHA1Context);
procedure HashSHA1(var Digest : TSHA1Digest;
const Buf; BufSize : Longint);
procedure UpdateSHA1(var Context : TSHA1Context;
const Buf; BufSize: Longint);
procedure FinalizeSHA1(var Context: TSHA1Context;
var Digest : TSHA1Digest);
procedure StringHashSHA1(var Digest : TSHA1Digest;
const Str : {$IFDEF LOCKBOXUNICODE}UnicodeString{$ELSE}AnsiString{$ENDIF}); stdcall;
{ Misc public utilities }
{function Ran01(var Seed : LongInt) : LongInt;
function Ran02(var Seed : LongInt) : LongInt;
function Ran03(var Seed : LongInt) : LongInt;
function Random32Byte(var Seed : LongInt) : Byte;
function Random64Byte(var Seed : TInt64) : Byte;
procedure ShrinkDESKey(var Key : TKey64); }
procedure XorMem(var Mem1; const Mem2; Count : Cardinal);
function RolX(I, C : DWord) : DWord; register;
procedure XorMemPrim(var Mem1; const Mem2; Count : Cardinal); register;
asm
push esi
push edi
mov esi, eax //esi = Mem1
mov edi, edx //edi = Mem2
push ecx //save byte count
shr ecx, 2 //convert to dwords
jz @Continue
cld
@Loop1: //xor dwords at a time
mov eax, [edi]
xor [esi], eax
add esi, 4
add edi, 4
dec ecx
jnz @Loop1
@Continue: //handle remaining bytes (3 or less)
pop ecx
and ecx, 3
jz @Done
@Loop2: //xor remaining bytes
mov al, [edi]
xor [esi], al
inc esi
inc edi
dec ecx
jnz @Loop2
@Done:
pop edi
pop esi
end;
{ -------------------------------------------------------------------------- }
procedure XorMem(var Mem1; const Mem2; Count : Cardinal);
begin
XorMemPrim(Mem1, Mem2, Count);
end;
{ == SHA-1 hashing routines ================================================ }
procedure SHA1Clear( var Context : TSHA1Context );
begin
fillchar( Context, SizeOf( Context ), $00 );
end;
{ -------------------------------------------------------------------------- }
function SHA1SwapByteOrder( n : DWORD ) : DWORD;
begin
n := ( n shr 24 ) or (( n shr 8 ) and LBMASK_LO )
or (( n shl 8 ) and LBMASK_HI ) or ( n shl 24 );
Result := n;
end;
{ -------------------------------------------------------------------------- }
procedure HashSHA1( var Digest : TSHA1Digest; const Buf; BufSize : Longint );
var
Context : TSHA1Context;
begin
InitSHA1( Context );
UpdateSHA1( Context, Buf, BufSize );
FinalizeSHA1( Context, Digest );
end;
{ -------------------------------------------------------------------------- }
{$IFDEF UNICODE}
procedure StringHashSHA1W(var Digest : TSHA1Digest; const Str : UnicodeString);
begin
HashSHA1(Digest, Str[1], Length(Str) * SizeOf(WideChar));
end;
{$ENDIF}
procedure StringHashSHA1A(var Digest : TSHA1Digest; const Str : AnsiString);
begin
HashSHA1(Digest, Str[1], Length(Str) * SizeOf(AnsiChar));
end;
{ -------------------------------------------------------------------------- }
procedure SHA1Hash( var Context : TSHA1Context );
var
A : DWord;
B : DWord;
C : DWord;
D : DWord;
E : DWord;
X : DWord;
W : array[ 0..79 ] of DWord;
i : Longint;
begin
with Context do begin
sdIndex:= 0;
Move( sdBuf, W, Sizeof( W ));
// W := Mt, for t = 0 to 15 : Mt is M sub t
for i := 0 to 15 do
W[ i ]:= SHA1SwapByteOrder( W[ i ] );
// Transform Message block from 16 32 bit words to 80 32 bit words
// Wt, = ( Wt-3 xor Wt-8 xor Wt-13 xor Wt-16 ) rolL 1 : Wt is W sub t
for i:= 16 to 79 do
W[i]:= RolX( W[ i - 3 ] xor W[ i - 8 ] xor W[ i - 14 ] xor W[ i - 16 ], 1 );
A := sdHash[ 0 ];
B := sdHash[ 1 ];
C := sdHash[ 2 ];
D := sdHash[ 3 ];
E := sdHash[ 4 ];
// the four rounds
for i:= 0 to 19 do begin
X := RolX( A, 5 ) + ( D xor ( B and ( C xor D ))) + E + W[ i ] + SHA1_K1;
E := D;
D := C;
C := RolX( B, 30 );
B := A;
A := X;
end;
for i:= 20 to 39 do begin
X := RolX( A, 5 ) + ( B xor C xor D ) + E + W[ i ] + SHA1_K2;
E := D;
D := C;
C := RolX( B, 30 );
B := A;
A := X;
end;
for i:= 40 to 59 do begin
X := RolX( A, 5 ) + (( B and C ) or ( D and ( B or C ))) + E + W[ i ] + SHA1_K3;
E := D;
D := C;
C := RolX( B, 30 );
B := A;
A := X;
end;
for i:= 60 to 79 do
begin
X := RolX( A, 5 ) + ( B xor C xor D ) + E + W[ i ] + SHA1_K4;
E := D;
D := C;
C := RolX( B, 30 );
B := A;
A := X;
end;
sdHash[ 0 ]:= sdHash[ 0 ] + A;
sdHash[ 1 ]:= sdHash[ 1 ] + B;
sdHash[ 2 ]:= sdHash[ 2 ] + C;
sdHash[ 3 ]:= sdHash[ 3 ] + D;
sdHash[ 4 ]:= sdHash[ 4 ] + E;
FillChar( W, Sizeof( W ), $00 );
FillChar( sdBuf, Sizeof( sdBuf ), $00 );
end;
end;
{ -------------------------------------------------------------------------- }
procedure SHA1UpdateLen( var Context : TSHA1Context; Len : DWord );
begin
Inc( Context.sdLo,( Len shl 3 ));
if Context.sdLo < ( Len shl 3 ) then
Inc( Context.sdHi );
Inc( Context.sdHi, Len shr 29 );
end;
{ -------------------------------------------------------------------------- }
procedure InitSHA1( var Context : TSHA1Context );
begin
SHA1Clear( Context );
Context.sdHash[ 0 ] := SHA1_A;
Context.sdHash[ 1 ] := SHA1_B;
Context.sdHash[ 2 ] := SHA1_C;
Context.sdHash[ 3 ] := SHA1_D;
Context.sdHash[ 4 ] := SHA1_E;
end;
{ -------------------------------------------------------------------------- }
procedure UpdateSHA1( var Context : TSHA1Context; const Buf; BufSize: Longint );
var
PBuf: ^Byte;
begin
with Context do begin
SHA1UpdateLen( Context, BufSize );
PBuf := @Buf;
while BufSize > 0 do begin
if ( Sizeof( sdBuf ) - sdIndex ) <= DWord( BufSize ) then begin
Move( PBuf^, sdBuf[ sdIndex ], Sizeof( sdBuf ) - sdIndex );
Dec( BufSize, Sizeof( sdBuf ) - sdIndex );
Inc( PBuf, Sizeof( sdBuf ) - sdIndex );
SHA1Hash( Context );
end else begin
Move( PBuf^, sdBuf[ sdIndex ], BufSize );
Inc( sdIndex, BufSize );
BufSize := 0;
end;
end;
end;
end;
{ -------------------------------------------------------------------------- }
procedure FinalizeSHA1( var Context : TSHA1Context; var Digest : TSHA1Digest );
begin
with Context do begin
sdBuf[ sdIndex ] := $80;
if sdIndex >= 56 then
SHA1Hash( Context );
PDWord( @sdBuf[ 56 ])^ := SHA1SwapByteOrder( sdHi );
PDWord( @sdBuf[ 60 ])^ := SHA1SwapByteOrder( sdLo );
SHA1Hash( Context );
sdHash[ 0 ] := SHA1SwapByteOrder( sdHash[ 0 ]);
sdHash[ 1 ] := SHA1SwapByteOrder( sdHash[ 1 ]);
sdHash[ 2 ] := SHA1SwapByteOrder( sdHash[ 2 ]);
sdHash[ 3 ] := SHA1SwapByteOrder( sdHash[ 3 ]);
sdHash[ 4 ] := SHA1SwapByteOrder( sdHash[ 4 ]);
Move( sdHash, Digest, Sizeof( Digest ));
SHA1Clear( Context );
end;
end;
procedure StringHashSHA1(var Digest : TSHA1Digest; const Str : {$IFDEF LOCKBOXUNICODE}UnicodeString{$ELSE}AnsiString{$ENDIF}); export; stdcall;
begin
{$IFDEF LOCKBOXUNICODE}
StringHashSHA1W(Digest, Str);
{$ELSE}
StringHashSHA1A(Digest, Str);
{$ENDIF}
end;
EXPORTS
StringHashSHA1;
begin
end.
答案 0 :(得分:1)
您从单元中解除了此代码。该单元具有单独的接口和实现部分,但您已将它们合并为一个部分(根据dpr文件的要求)。在实现部分中有一些声明的函数,但是如果没有该部分,Delphi会将每个函数声明解释为另一个嵌套函数的开头。最后,我们在几个嵌套函数中到达文件的末尾,并且在该上下文中不允许exports
。
将forward
添加到文件顶部的声明中(从InitSHA1
到RolX
),将其标记为声明而不是定义。