忽略C函数中的参数

忽略C函数中的参数,c,C,我正在将C库集成到iOS的Objective-C应用程序中。我不是很懂C语言。。。我知道的足够危险了 C函数声明如下: extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, unz_file_info *pfile_info, char *szFileName, uLong fileN

我正在将C库集成到iOS的Objective-C应用程序中。我不是很懂C语言。。。我知道的足够危险了

C函数声明如下:

extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
                         unz_file_info *pfile_info,
                         char *szFileName,
                         uLong fileNameBufferSize,
                         void *extraField,
                         uLong extraFieldBufferSize,
                         char *szComment,
                         uLong commentBufferSize));
我真的只对
szFileName
感兴趣。我知道我可以通过传递
NULL
忽略
void*
char*
。我可以传递某种类型的
NULL
-相当于
uLong
参数吗?我收到一个编译器警告,它会在不进行转换的情况下转换为指针

这是我调用这个函数的循环,以防有人对此发表评论。我是否正确地使用了
malloc
/
free
?我不习惯低级的C语言。我知道人们抱怨Objective-C引用计数,但相比之下,它相当奢侈:)

我能给你递点什么吗 与uLong参数等效的NULL

0
怎么样

我是否正确地使用了
malloc
/
free

我觉得还可以

但是您还有一些其他错误:
fileNameBufferSize
应该是
szFileName
缓冲区的大小(代码中为1024)。你没有填,这意味着这是垃圾,小心点

编辑

是的,您应该检查
malloc
返回的值是否为NULL,忘了提到这一点

我可以传递某种类型的
NULL
-相当于uLong参数吗?我收到一条编译器警告,关于在没有强制转换的情况下转换为指针

不一般;参数的允许值应该列在正在嵌入的库的手册中(zlib,诸如此类)。不要将
NULL
传递给需要
long
的函数,这是无效的

更糟糕的是:您正在将未初始化变量
fileNameBufferSize
extraFieldBufferSize
commentBufferSize
的值传递给函数。您的程序具有未定义的行为。适当地设置这些变量,或者为参数使用文字/表达式

我是否正确地使用了
malloc
/
free

您忘记从
malloc
检查返回值。始终检查空值。更好的是:由于您分配的内存量是恒定的,所以只需在堆栈上执行此操作:

char szFileName[1024];
不需要
malloc
free
。(并且您可能希望使用
PATH\u MAX
而不是任意的1024。如果路径名可能比您平台上的长呢?)

编辑:不要在意
路径_MAX
部分;这个字符串的最大长度应该记录在zlib文档中,因为它不是系统中某个部件的最大长度,而是zlib愿意存储的最大长度

我可以传递某种与uLong参数等价的NULL吗

非指针参数没有全局接受的NULL;这取决于功能。在某些情况下,可以传入0,但并不总是这样


在本例中,您传递的是缓冲区的大小,并为缓冲区提供NULL,因此传递0是正确的似乎是合乎逻辑的。

ulong参数是缓冲区参数的大小。这是为了让函数知道这些缓冲区有多大,从而不会溢出它们

如果需要fileName参数,则必须提供正确的fileNameBufferSize

至于您是否真的可以传递一个指向指针参数的空指针,只有该函数的文档(或源代码)可以告诉您。或者,如果文档没有告诉您,您必须对函数进行一些基础科学实验,看看它是如何工作的

假设函数接受不需要填充的参数的空指针,则可能会将0作为ulong参数的值传递

您必须执行以下操作:

unz_file_info pfile_info;
char *szFileName = malloc(1024);
uLong fileNameBufferSize = 1024;
if( szFileName == NULL) {
  //handle error
  return;
}

do {
    int ret = unzGetCurrentFileInfo(zipFile, &pfile_info, szFileName, fileNameBufferSize, NULL, 0, NULL, 0);
    NSLog(@"get info ret %i filename size %lu, filename %s", ret, pfile_info.size_filename, szFileName);
    // do other stuff here with the filename
}
while (unzGoToNextFile(zipFile) == UNZ_OK);
free(szFileName);
您还应该研究unzGetCurrentFileInfo返回值的含义。如果失败,则不太可能使用函数的
szFileName
或任何其他参数-因此,如果函数失败,请不要使用这些变量调用NSLog

在这种情况下,malloc似乎没有必要。只需使用本地数组,并放弃free()调用


我会按照这些思路来做一些事情。我删除了未使用的变量,而不是malloc/free,只需在堆栈中进行简单的分配即可

#define FNAME_SZ 1024 //should really read the docs on your target platform to find the proper size
unz_file_info pfile_info;
char szFileName[FNAME_SZ];

//initialize. important just to be sure
memset(szFileName, 0, FNAME_SZ);

do {
    int ret = unzGetCurrentFileInfo(zipFile, &pfile_info, szFileName, FNAME_SZ, NULL, 0, NULL, 0);
    NSLog(@"get info ret %i filename size %lu, filename %s", ret, pfile_info.size_filename, szFileName);
    // do other stuff here with the filename
}
while (unzGoToNextFile(zipFile) == UNZ_OK);

哦,太好了。。。我误解了fileNameBufferLength是什么,我以为它将用文件名的长度填充,我没有意识到我在告诉函数我分配了多大的缓冲区!(这对我来说似乎很奇怪,因为如果我分配的缓冲区太小怎么办?我猜函数只会截断结果,但这似乎是一件愚蠢的事情。)截断结果似乎是一件愚蠢的事情,但函数别无选择。如果它想写100个字节,但是你给它一个只有80个字节的缓冲区,那么它就不能写额外的20个字节,否则它将覆盖内存,并可能带来灾难性的结果。除了截断字符串,它什么也做不了。
char szFileName[1024];
uLong fileNameBufferSize = sizeof szFileName;
#define FNAME_SZ 1024 //should really read the docs on your target platform to find the proper size
unz_file_info pfile_info;
char szFileName[FNAME_SZ];

//initialize. important just to be sure
memset(szFileName, 0, FNAME_SZ);

do {
    int ret = unzGetCurrentFileInfo(zipFile, &pfile_info, szFileName, FNAME_SZ, NULL, 0, NULL, 0);
    NSLog(@"get info ret %i filename size %lu, filename %s", ret, pfile_info.size_filename, szFileName);
    // do other stuff here with the filename
}
while (unzGoToNextFile(zipFile) == UNZ_OK);