我仍然非常擅长用C语言编程,所以我使用Mingw在我的系统上编译。
我有以下程序,并提供了很多帮助。它将爆炸PKWare DCL压缩.vol存档(文件ID RESLIST)并将文件解压缩到指定的输出文件夹,为解压缩的文件提供原始.vol文件的修改日期。它应该用于Inno安装程序安装程序,我想看看我是否可以将其编译为.dll库我可以在我的.iss脚本中导入,即:
function VolEx( filename, outputpath: String ): Integer; external 'VolExA@volex.dll stdcall';
我通过http://www.mingw.org/wiki/sampleDLL阅读,但很难理解所有ifdefs和extern“C”的内容。
此外,我希望它能够更改我的安装程序中的WizardForm.FilenameLabel.Caption以匹配当前正在提取的文件(我知道这需要InnoTools InnoCallback http://www.sherlocksoftware.org/page.php?id=54;类似于FreeArc { {3}})
Volex.c(包括blast.c和blast.h,来自这里:http://freearc.org/InnoSetup.aspx)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
#include <time.h>
#include <utime.h>
#include "blast.h"
#define local static
#define VOLID "RESLIST"
struct inbuf {
unsigned long left;
unsigned char *buf;
unsigned size;
FILE *in;
};
struct stat statbuf;
time_t mtime;
time_t voltime;
struct utimbuf new_times;
local unsigned inf(void *how, unsigned char **buf)
{
unsigned len;
struct inbuf *inb = how;
len = inb->size > inb->left ? inb->left : inb->size;
len = fread(inb->buf, 1, len, inb->in);
inb->left -= len;
*buf = inb->buf;
return len;
}
local int outf(void *how, unsigned char *buf, unsigned len)
{
return fwrite(buf, 1, len, (FILE *)how) != len;
}
#define BUFSIZE 16384 /* must fit in unsigned */
local int extract(char *name, unsigned long len, FILE *in, char *path, time_t prevtime)
{
int err;
FILE *out;
struct inbuf inb;
unsigned char buf[BUFSIZE];
inb.left = len;
inb.buf = buf;
inb.size = BUFSIZE;
inb.in = in;
mkdir(path);
char outPath[strlen(path) + 20];
strcpy(outPath, path);
strcat(outPath, "\\");
strcat(outPath, name);
out = fopen(outPath, "wb");
if (out == NULL)
return 2;
err = blast(inf, &inb, outf, out);
fclose(out);
if (stat(outPath, &statbuf) < 0) {
perror(outPath);
return 1;
}
mtime = statbuf.st_mtime; /* seconds since the epoch */
new_times.actime = statbuf.st_atime; /* keep atime unchanged */
new_times.modtime = prevtime; /* set mtime to current time */
if (utime(outPath, &new_times) < 0) {
perror(outPath);
return 1;
}
return err;
}
int main(int argc, char *argv[])
{
if ( argc != 3 )
{
printf( "Usage: %s <vol> <output path>", argv[0] );
return 1;
}
else
{
FILE *in = fopen(argv[1],"rb");
unsigned long off, next;
int err;
unsigned char head[24];
if (stat(argv[1], &statbuf) < 0) {
perror(argv[1]);
return 1;
}
voltime = statbuf.st_mtime; /* seconds since the epoch */
if (fread(head, 1, 8, in) != 8 || memcmp(head, VOLID, 8)) {
fprintf(stderr, "not the expected .vol format\n");
return 1;
}
off = 8;
while ((next = fread(head, 1, 24, in)) == 24) {
off += 24;
next = head[20] + (head[21] << 8) + ((unsigned long)(head[22]) << 16) +
((unsigned long)(head[23]) << 24);
head[20] = 0;
err = extract((char *)head, next - off, in, argv[2], voltime);
if (err) {
fprintf(stderr, "extraction error %d on %s\n", err, head);
return 1;
}
off = next;
}
if (next)
fprintf(stderr, "%lu bytes ignored at the end\n", next);
return 0;
}
}
答案 0 :(得分:1)
假设您正在使用ANSI Inno Setup,请使用以下Inno签名:
function VolEx( filename, outputpath: String ): Integer; external 'VolExA@volex.dll stdcall';
将在您的DLL代码中需要以下C签名:
int __stdcall __declspec(dllexport) VolExA(const char *filename, const char *outputpath);
(如果您将DLL编译为C ++而不是C,则开头也需要extern "C"
。)
您需要在DLL中声明此函数并将相应的代码从上面的“main”移动到其中,然后删除main函数并编译为DLL而不是控制台应用程序。
在担心通过回调反馈之前先让这部分工作 - 如果你遇到问题就提交一个单独的问题。