忽略C函数中的参数
我正在将C库集成到iOS的Objective-C应用程序中。我不是很懂C语言。。。我知道的足够危险了 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
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);