为什么编译器不识别" exports"当我将一个单位转换成一个独立的项目?

时间:2016-10-22 10:30:01

标签: delphi dll

我有一个遗留加密pas文件,我想编译成一个DLL,我可以从C#应用程序调用。

我对Delphi一无所知并且正在使用Delphi XE2。

我正在尝试导出过程StringHashSHA1。

尝试构建DLL时,我得到以下错误:

  • 预计BEGIN但在......
  • 收到了出口
  • 未声明的标识符StringHashSHA1 at ...

我看不出我哪里出错了。 如何将以下代码编译为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.

1 个答案:

答案 0 :(得分:1)

您从单元中解除了此代码。该单元具有单独的接口和实现部分,但您已将它们合并为一个部分(根据dpr文件的要求)。在实现部分中有一些声明的函数,但是如果没有该部分,Delphi会将每个函数声明解释为另一个嵌套函数的开头。最后,我们在几个嵌套函数中到达文件的末尾,并且在该上下文中不允许exports

forward添加到文件顶部的声明中(从InitSHA1RolX),将其标记为声明而不是定义。