C++ To Delphi 或者能否让Borland C++编译成obj文件,让delphi连接,从而不用dll文件。 (300分)

  • 主题发起人 yuki2003
  • 开始时间
Y

yuki2003

Unregistered / Unconfirmed
GUEST, unregistred user!
这是在C++通过的代码,我需要翻译成Delphi,不想调用dll文件了。
###################################
或者能否让Borland C++编译成obj文件,让delphi连接,从而不用dll文件。
###################################
请问C++的"zlib.h"跟Delphi的"zlib.pas"能转化过来吗。
我发现Borland C++编译的obj文件,能让delphi连接起来,但微软的c++不行。
以下代码是有关解压缩的,有两种情况,LZ77与zlib。
请帮我翻译一下,谢谢。(问题的最高价值分是300啊,我打算出400的[:(],害得我又重打了一次,300可以了吧,帮帮忙了[:)])
// HPIUtil.DLL
// Routines for accessing HPI files
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "HPIUtil.h"
#include "zlib.h"
#define HEX_HAPI 0x49504148
// 'BANK'
#define HEX_BANK 0x4B4E4142
// 'SQSH'
#define HEX_SQSH 0x48535153
#define HEX_MARKER 0x00010000
#define OUTBLOCKSIZE 16384
#define INBLOCKSIZE (65536+17)
#pragma pack(1)
typedef struct _HPIHEADER {
long HPIMarker;
/* 'HAPI' */
long SaveMarker;
/* 'BANK' if savegame */
long DirectorySize;
/* Directory size */
long Key;
/* decode key */
long Start;
/* offset of directory */
} HPIHEADER;
typedef struct _HPIENTRY {
int NameOffset;
int CountOffset;
char Flag;
} HPIENTRY;
typedef struct _HPICHUNK {
long Marker;
/* always 0x48535153 (SQSH) */
char Unknown1;
/* I have no idea what these mean */
char CompMethod; /* 1=lz77 2=zlib */
char Encrypt;
/* Is the chunk encrypted? */
long CompressedSize;
/* the length of the compressed data */
long DecompressedSize;
/* the length of the decompressed data */
long Checksum;
/* check sum */
} HPICHUNK;
typedef struct _HPIFILE {
HANDLE f;
// handle to open file
LPSTR d;
// pointer to decrypted directory
int Key; // Key
int Start;
// Start of directory
} HPIFILE;
typedef struct _DIRENTRY {
struct _DIRENTRY *Next;
struct _DIRENTRY *Prev;
struct _DIRENTRY *FirstSub;
struct _DIRENTRY *LastSub;
int dirflag;
int count;
int *DirOffset;
LPSTR Name;
LPSTR FileName;
int memflag;
} DIRENTRY;
typedef struct _TREENODE {
struct _TREENODE *tree_l;
struct _TREENODE *tree_r;
int tree_b;
void *tree_p;
} TREENODE;
#pragma pack()
HINSTANCE hThisInstance;
const char szAppTitle[] = "HPIUtil";
const char szTrailer[] = "HPIPack by Joe D (joed@cws.org) FNORD Total Annihilation Copyright 1997 Cavedog Entertainment";
char DirPath[256];
HPIENTRY *DirEntry;
HANDLE ProgHeap = NULL;
static LPVOID GetMem(int size, int zero)
{
return HeapAlloc(ProgHeap, (zero ? HEAP_ZERO_MEMORY : 0), size);
}
static void FreeMem(LPVOID x)
{
HeapFree(ProgHeap, 0, x);
}
static LPSTR DupString(LPSTR x)
{
LPSTR s = GetMem(strlen(x)+1, FALSE);
strcpy(s, x);
return s;
}
static int ReadAndDecrypt(HPIFILE *hpi, int fpos, LPSTR buff, int buffsize)
{
int count;
int tkey;
int result;

SetFilePointer(hpi->f, fpos, NULL, FILE_begin
);
if (!ReadFile(hpi->f, buff, buffsize, &amp;result, NULL))
return 0;
if (hpi->Key) {
for (count = 0;
count < result;
count++) {
tkey = (fpos + count) ^ hpi->Key;
buff[count] = tkey ^ ~buff[count];
}
}
return result;
}
int ZLibDecompress(char *out, char *in, HPICHUNK *Chunk)
{
z_stream zs;
int result;
zs.next_in = in;
zs.avail_in = Chunk->CompressedSize;
zs.total_in = 0;
zs.next_out = out;
zs.avail_out = 65536;
zs.total_out = 0;
zs.msg = NULL;
zs.state = NULL;
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = NULL;
zs.data_type = Z_BINARY;
zs.adler = 0;
zs.reserved = 0;
result = inflateInit(&amp;zs);
if (result != Z_OK) {
return 0;
}
result = inflate(&amp;zs, Z_FINISH);
if (result != Z_STREAM_END) {
zs.total_out = 0;
}
result = inflateEnd(&amp;zs);
if (result != Z_OK) {
return 0;
}
return zs.total_out;
}
static int LZ77Decompress(char *out, char *in, HPICHUNK *Chunk)
{
int x;
int work1;
int work2;
int work3;
int inptr;
int outptr;
int count;
intdo
ne;
char DBuff[4096];
int DPtr;
done = FALSE;
inptr = 0;
outptr = 0;
work1 = 1;
work2 = 1;
work3 = in[inptr++];

while (!done) {
if ((work2 &amp;
work3) == 0) {
out[outptr++] = in[inptr];
DBuff[work1] = in[inptr];
work1 = (work1 + 1) &amp;
0xFFF;
inptr++;
}
else
{
count = *((unsigned short *) (in+inptr));
inptr += 2;
DPtr = count >> 4;
if (DPtr == 0) {
return outptr;
}
else
{
count = (count &amp;
0x0f) + 2;
if (count >= 0) {
for (x = 0;
x < count;
x++) {
out[outptr++] = DBuff[DPtr];
DBuff[work1] = DBuff[DPtr];
DPtr = (DPtr + 1) &amp;
0xFFF;
work1 = (work1 + 1) &amp;
0xFFF;
}
}
}
}
work2 *= 2;
if (work2 &amp;
0x0100) {
work2 = 1;
work3 = in[inptr++];
}
}
return outptr;
}
static int Decompress(char *out, char *in, HPICHUNK *Chunk)
{
int x;
int Checksum;
Checksum = 0;
for (x = 0;
x < Chunk->CompressedSize;
x++) {
Checksum += (unsigned char) in[x];
if (Chunk->Encrypt)
in[x] = (in[x] - x) ^ x;
}
if (Chunk->Checksum != Checksum) {
return 0;
}
switch (Chunk->CompMethod) {
case 1 : return LZ77Decompress(out, in, Chunk);
case 2 : return ZLibDecompress(out, in, Chunk);
default : return 0;
}
}

static LPSTR DecodeFileToMem(HPIFILE *hpi, HPIENTRY *Entry)
{
HPICHUNK *Chunk;
long *DeSize;
int DeCount;
int DeLen;
int x;
char *DeBuff;
char *WriteBuff;
int WriteSize;
int WritePtr;
int Offset;
int Length;
char FileFlag;
if (!Entry)
return NULL;
Offset = *((int *) (hpi->d + Entry->CountOffset));
Length = *((int *) (hpi->d + Entry->CountOffset + 4));
FileFlag = *(hpi->d + Entry->CountOffset + 8);
//if (FileFlag != 1)
// return NULL;
WriteBuff = GlobalAlloc(GPTR, Length+1);
if (!WriteBuff) {
return NULL;
}
WriteBuff[Length] = 0;
if (FileFlag) {
DeCount = Length / 65536;
if (Length % 65536)
DeCount++;
DeLen = DeCount * sizeof(int);
DeSize = GetMem(DeLen, TRUE);
ReadAndDecrypt(hpi, Offset, (char *) DeSize, DeLen);
Offset += DeLen;

WritePtr = 0;
for (x = 0;
x < DeCount;
x++) {
Chunk = GetMem(DeSize[x], TRUE);
ReadAndDecrypt(hpi, Offset, (char *) Chunk, DeSize[x]);
Offset += DeSize[x];
DeBuff = (char *) (Chunk+1);
WriteSize = Decompress(WriteBuff+WritePtr, DeBuff, Chunk);
WritePtr += WriteSize;
FreeMem(Chunk);
}
FreeMem(DeSize);
}
else
{
ReadAndDecrypt(hpi, Offset, WriteBuff, Length);
}
return WriteBuff;
}
LPVOID WINAPI HPIOpen(LPSTR FileName)
{
HANDLE f;
HPIHEADER Header;
int BytesRead;
HPIFILE *hpi;
f = CreateFile(FileName, GENERIC_READ, (FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL, OPEN_EXISTING, (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS),
NULL);
if (f == INVALID_HANDLE_VALUE) {
return NULL;
}
if (!ReadFile(f, &amp;Header, sizeof(Header), &amp;BytesRead, NULL)) {
CloseHandle(f);
return NULL;
}
if (BytesRead != sizeof(Header)) {
CloseHandle(f);
return NULL;
}
if (Header.HPIMarker != HEX_HAPI) { /* 'HAPI' */
CloseHandle(f);
return NULL;
}
if (Header.SaveMarker != HEX_MARKER) {
CloseHandle(f);
return NULL;
}
hpi = GetMem(sizeof(HPIFILE), TRUE);
hpi->f = f;
if (Header.Key)
hpi->Key = ~((Header.Key * 4) | (Header.Key >> 6));
else
hpi->Key = 0;
hpi->Start = Header.Start;
hpi->d = GetMem(Header.DirectorySize, TRUE);
BytesRead = ReadAndDecrypt(hpi, Header.Start, hpi->d+Header.Start, Header.DirectorySize-Header.Start);
if (BytesRead != (Header.DirectorySize-Header.Start)) {
FreeMem(hpi->d);
FreeMem(hpi);
CloseHandle(f);
return NULL;
}
return hpi;
}
static int ListDirectory(HPIFILE *hpi, int offset, LPSTR Path, int Next, int This)
{
int *Entries;
HPIENTRY *Entry;
int count;
char *Name;
int *EntryOffset;
char MyPath[1024];
Entries = (int *) (hpi->d + offset);
EntryOffset = Entries + 1;
Entry = (HPIENTRY *) (hpi->d + *EntryOffset);
for (count = 0;
count < *Entries;
count++) {
Name = hpi->d + Entry->NameOffset;
strcpy(MyPath, Path);
if (*Path)
strcat(MyPath, "//");
strcat(MyPath, Name);
if (This == Next) {
if (!DirEntry) {
DirEntry = Entry;
lstrcpy(DirPath, MyPath);
}
return This;
}
This++;
if (Entry->Flag == 1) {
This = ListDirectory(hpi, Entry->CountOffset, MyPath, Next, This);
}
Entry++;
}
return This;
}
LRESULT WINAPI HPIGetFiles(HPIFILE *hpi, int Next, LPSTR Name, LPINT Type, LPINT Size)
{
int result;
int *Count;
*Name = 0;
*Type = 0;
*Size = 0;
DirEntry = NULL;
DirPath[0] = 0;
result = ListDirectory(hpi, hpi->Start, "", Next, 0);
if (!DirEntry)
return 0;
lstrcpy(Name, DirPath);
Count = (int *) (hpi->d + DirEntry->CountOffset);
*Type = DirEntry->Flag;
if (!*Type)
Count++;
*Size = *Count;
return result+1;
}
static int EnumDirectory(HPIFILE *hpi, int offset, LPSTR Path, int Next, LPSTR DirName, int This)
{
int *Entries;
HPIENTRY *Entry;
int count;
int *EntryOffset;
char MyPath[1024];
Entries = (int *) (hpi->d + offset);
EntryOffset = Entries + 1;
Entry = (HPIENTRY *) (hpi->d + *EntryOffset);
//MessageBox(NULL, Path, "Searching", MB_OK);
for (count = 0;
count < *Entries;
count++) {
if (lstrcmpi(Path, DirName) == 0) {
if (This >= Next) {
if (!DirEntry) {
DirEntry = Entry;
//MessageBox(NULL, hpi->d + Entry->NameOffset, "Found", MB_OK);
//lstrcpy(DirPath, MyPath);
}
return This;
}
This++;
}
if (Entry->Flag == 1) {
lstrcpy(MyPath, Path);
if (*Path)
lstrcat(MyPath, "//");
lstrcat(MyPath, (hpi->d + Entry->NameOffset));
//MessageBox(NULL, MyPath, "recursing", MB_OK);
This = EnumDirectory(hpi, Entry->CountOffset, MyPath, Next, DirName, This);
if (DirEntry)
return This;
}
Entry++;
}
return This;
}
LRESULT WINAPI HPIClose(HPIFILE *hpi)
{
if (!hpi)
return 0;
if (hpi->f)
CloseHandle(hpi->f);
if (hpi->d)
FreeMem(hpi->d);
FreeMem(hpi);
return 0;
}
static LPSTR SearchForFile(HPIFILE *hpi, int offset, LPSTR Path, LPSTR FName)
{
int *Entries;
HPIENTRY *Entry;
int count;
char *Name;
int *EntryOffset;
char MyPath[1024];
LPSTR result;
Entries = (int *) (hpi->d + offset);
EntryOffset = Entries + 1;
Entry = (HPIENTRY *) (hpi->d + *EntryOffset);
for (count = 0;
count < *Entries;
count++) {
Name = hpi->d + Entry->NameOffset;
strcpy(MyPath, Path);
if (*Path)
strcat(MyPath, "//");
strcat(MyPath, Name);
if (Entry->Flag == 1) {
result = SearchForFile(hpi, Entry->CountOffset, MyPath, FName);
if (result)
return result;
}
else
{
if (lstrcmpi(MyPath, FName) == 0) {
DirEntry = Entry;
return DecodeFileToMem(hpi, Entry);
}
}
Entry++;
}
return NULL;
}
LRESULT WINAPI HPICloseFile(LPSTR FileHandle)
{
if (FileHandle)
GlobalFree(FileHandle);
return 0;
}
LRESULT WINAPI HPIExtractFile(HPIFILE *hpi, LPSTR FileName, LPSTR ExtractName)
{
LPSTR data;
HANDLE f;
int *Size;
int Written;
DirEntry = NULL;
data = SearchForFile(hpi, hpi->Start, "", FileName);
if (!data)
return 0;
Size = (int *) (hpi->d + DirEntry->CountOffset);
if (!DirEntry->Flag)
Size++;
else
{
HPICloseFile(data);
return 0;
}
f = CreateFile(ExtractName, GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
NULL);
if (f == INVALID_HANDLE_VALUE) {
HPICloseFile(data);
return 0;
}
WriteFile(f, data, *Size, &amp;Written, NULL);
CloseHandle(f);
HPICloseFile(data);
return 1;
}
static DIRENTRY *CreatePath(DIRENTRY *dir, LPSTR FName)
{
LPSTR p;
char Path[MAX_PATH];
LPSTR n;
DIRENTRY *d;
DIRENTRY *e;
p = FName;
d = dir->FirstSub;
while (*p) {
n = Path;
while (*p &amp;&amp;
(*p != '//'))
*n++ = *p++;
*n = 0;
if (*p)
p++;
while (d) {
if (stricmp(d->Name, Path) == 0) {
if (d->dirflag) {
break;
}
else
return NULL;
// found, but not a directory
}
d = d->Next;
}
if (d) {
dir = d;
}
else
{
e = GetMem(sizeof(DIRENTRY), TRUE);
e->dirflag = TRUE;
e->Name = DupString(Path);
if (dir->LastSub) {
dir->LastSub->Next = e;
e->Prev = dir->LastSub;
dir->LastSub = e;
}
else
{
dir->FirstSub = e;
dir->LastSub = e;
}
dir = e;
}
d = dir->FirstSub;
}
return dir;
}
int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH :
hThisInstance = hInstance;
ProgHeap = HeapCreate(0, 250000, 0);
break;
case DLL_THREAD_ATTACH :
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH :
if (ProgHeap) {
HeapDestroy(ProgHeap);
ProgHeap = NULL;
}
break;
}
return TRUE;
}
 
L

LuJuhe

Unregistered / Unconfirmed
GUEST, unregistred user!
用vclzip控件不好吗?
除非很空闲的人,不然没人愿意花一天以上的时间来做这样的翻译工作吧。
 
Y

yuki2003

Unregistered / Unconfirmed
GUEST, unregistred user!
这是一种特殊的压缩文件,但它压缩的方式是很基本的,我已经吧代码精简到,
我只用的解压部分了。如果有了delphi的代码,我自己就可以做压缩的部分了
也可以做成自定义的格式了,掌握一点压缩数据的原理不是很好吗。
干脆问一句,这里有人玩《横扫千军》的游戏吗。这是解一代的文件的函数,解二代
文件的函数我也有。
 
M

Milpas

Unregistered / Unconfirmed
GUEST, unregistred user!
很早以前玩过横扫千军,哈哈
还是挺好玩的。。。。不过现在只玩帝国了
不好意思,帮不上忙
 
J

jsxjd

Unregistered / Unconfirmed
GUEST, unregistred user!
代码长了点吧!
 
J

jinmen

Unregistered / Unconfirmed
GUEST, unregistred user!
好像有软件可以把C++的声明部分翻译成Delphi的声明部分。
 
Y

yuki2003

Unregistered / Unconfirmed
GUEST, unregistred user!
国内很少玩横扫千军的,国外的玩家我觉得:不是c程序员就是3d设计者。
有哪个游戏可以自己编AI,做机器人啊。
苹果机上也有很多人玩。
现在的横扫千军我拥有300以上的兵种,有很多大机器人跑来跑去哦。能制造5000个单位上限。
上面的代码有很多空格跟{}的啊,没人帮忙的话,我自己也要翻译过来的。
苹果机的代码我也有了,就是不会用,真是伤心[:(][:(][:(]
 
Y

yuki2003

Unregistered / Unconfirmed
GUEST, unregistred user!
macrob.jpg

macross.jpg

com3g.jpg

98.jpg

125.jpg

115.jpg

 
S

simon707

Unregistered / Unconfirmed
GUEST, unregistred user!
太长了。
帮你UP一下吧!
 
T

tseug

Unregistered / Unconfirmed
GUEST, unregistred user!

{$L filename.OBJ}
参考D5开发人员指南, 13章
 
J

jsxjd

Unregistered / Unconfirmed
GUEST, unregistred user!
完全可以:
The external directive, which replaces the block in a procedure or function declaration, allows you to call procedures and functions that are compiled separately from your program.
Linking to .OBJ files
To call routines from a separately compiled .OBJ file, first link the .OBJ file to your application using the $L (or $LINK) compiler directive. For example,
{$L BLOCK.OBJ}
links BLOCK.OBJ into the program or unit in which it occurs. Next, declare the functions and procedures that you want to call:
procedure MoveWord(var Source, Dest;
Count: Integer);
external;
procedure FillWord(var Dest;
Data: Integer;
Count: Integer);
external;
Now you can call the MoveWord and FillWord routines from BLOCK.OBJ.
Declarations like the ones above are frequently used to access external routines written in assembly language. You can also place assembly-language routines directly in your Object Pascal source code;
for more information, see Inline assembler code.
Importing functions from DLLs
To import routines from a dynamic-link library, attach a directive of the form
external stringConstant;
to the end of a normal procedure or function header, where stringConstant is the name of the .DLL file in single quotation marks. For example,
function SomeFunction(S: string): string;
external 'strlib.dll';
imports a function called SomeFunction from STRLIB.DLL.
You can import a routine under a different name from the one it has in the DLL. If youdo
this, specify the original name in the external directive:
external stringConstant1 name stringConstant2;
where the first stringConstant gives the name of the .DLL file and the second stringConstant is the routine抯 original name. For example, the following declaration imports a function from USER32.DLL (part of the Windows API).
function MessageBox(HWnd: Integer;
Text, Caption: PChar;
Flags: Integer): Integer;
stdcall;
external 'user32.dll' name 'MessageBoxA';
The function抯 original name is MessageBoxA, but it is imported as MessageBox.
Instead of a name, you can use a number to identify the routine you want to import:
external stringConstant index integerConstant;
where integerConstant is the routine抯 index in the DLL export table.
In your importing declaration, be sure to match the exact spelling and case of the routine抯 name. Later, when you call the imported routine, the name is case-insensitive.
For more information about DLLs, see Dynamic-link libraries and packages.
 

卡色

Unregistered / Unconfirmed
GUEST, unregistred user!
太长了。
 
B

billjohn1999

Unregistered / Unconfirmed
GUEST, unregistred user!
Y

yuki2003

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢关注,我自己已经用delphi编出来了,不用翻译了,用delphi编很短的,不用那么长。
 
顶部