为什么Windows在调用函数时需要大小?

时间:2011-04-08 04:56:51

标签: c++ winapi

我正在尝试学习一点c ++而且我有一个愚蠢的问题。请考虑以下代码:

TCHAR tempPath[255];
GetTempPath(255, tempPath);

为什么windows需要var tempPath的大小?我看到GetTempPath被声明为:

GetTempPath(dword size, buf LPTSTR);

如果没有&运算符,窗口如何更改buf值?功能不应该那样吗?

GetTempPath(buf &LPTSTR);

有人可以提供简单的GetTempPath实施示例,以便了解size的使用方式吗?

修改

感谢您的所有答案,他们都是正确的,我给了你所有+1。但我的意思是“可以有人提供一个简单的GetTempPath实现”,我试图编写一个类似于Windows使用的函数,如下所示:

void MyGetTempPath(int size, char* buf) 
{
 buf = "C:\\test\\";
}

int main(int argc, char *argv[])
{
    char* tempPath = new TCHAR[255];
    GetTempPathA(255, tempPath);
    MessageBoxA(0, tempPath, "test", MB_OK);
    return EXIT_SUCCESS;
}

但它不起作用。 MessageBox显示“## $”字符串.MyGetTempPath如何编码才能正常工作?

7 个答案:

答案 0 :(得分:4)

Windows需要大小作为安全预防措施。如果应用程序将字符复制到缓冲区末尾,则可能会使应用程序崩溃。当你提供长度时,它可以阻止它。

数组变量就像指针一样工作。它们指向数组中的数据。因此,不需要&运算符。

不确定您正在寻找什么样的示例。就像我说的那样,它只需要验证它不会写出比空间更多的字符。

答案 1 :(得分:3)

数组不能按值传递到函数中。相反,它被转换为指向第一个元素的指针,并将其传递给函数。有一个(非const)指向数据的指针允许修改:

void foo(int* i)
{
    if (i) (don't dereference null)
        *i = 5; // dereference pointer, modify int
}

同样,该函数现在有一个指向它可以写入的TCHAR的指针。然后,它需要大小,因此它确切知道在初始版本之后存在多少TCHAR。否则它不知道数组有多大。

答案 2 :(得分:2)

如果您想避免尺寸,可以尝试以下包装:

template<typename CHAR_TYPE, unsigned int SIZE>
void MyGetTempPath (CHAR_TYPE (&array)[SIZE])  // 'return' value can be your choice
{
  GetTempPath(SIZE, array);
}

现在你可以使用如下:

TCHAR tempPath[255];
MyGetTempPath(tempPath);  // No need to pass size, it will count automatically

在您的另一个问题中,为什么我们不使用以下内容:

GetTempPath(buf &LPTSTR);

是因为,当您想要通过引用(而不是地址)传递数据类型时,使用&。我不知道buf是什么类型的,但它应该是一些指针类型。

答案 3 :(得分:2)

GetTempPath()输出到“tempPath”字符数组中。如果你没有告诉它在数组中分配了多少空间(255),它就无法知道它是否有足够的空间将路径字符串写入tempPath。

C / C ++中的字符数组几乎只是指向内存中位置的指针。它们不包含有关其自身的其他信息,例如C ++或Java类的实例。我认为,Windows API的主要功能是在C ++真正具有很大的惯性之前设计的,所以你经常需要使用旧的C风格技术和内置数据类型来处理它。

答案 4 :(得分:2)

  

有人可以提供一个简单的   GetTempPath实现示例所以我   可以看看尺寸是如何使用的?

第一种方式(基于MAX_PATH常量):

TCHAR szPath[MAX_PATH];
GetTempPath(MAX_PATH, szPath);

第二种方式(基于GetTempPath描述):

DWORD size;
LPTSTR lpszPath;
size = GetTempPath(0, NULL);
lpszPath = new TCHAR[size];
GetTempPath(size, lpszPath);
/* some code here */
delete[] lpszPath;
  

Windows如何在没有&amp;的情况下改变buf值。操作

&安培;不需要operator,因为array name是指向第一个数组元素(或所有数组)的指针。尝试下一个代码来演示:

TCHAR sz[1];
if ((void*)sz == (void*)&sz) _tprintf(TEXT("sz equals to &sz \n"));
if ((void*)sz == (void*)&(sz[0])) _tprintf(TEXT("sz equals to &(sz[0]) \n"));

答案 5 :(得分:1)

根据要求,这是一个非常简单的实现。

bool MyGetTempPath(size_t size, char* buf) 
{
    const char* path = "C:\\test\\";
    size_t len = strlen(path);

    if(buf == NULL)
        return false;

    if(size < len + 1)
        return false;

    strncpy(buf, path, size);

    return true;
}

调用新函数的示例:

char buffer[256];
bool success = MyGetTempPath(256, buffer);

答案 6 :(得分:0)

来自http://msdn.microsoft.com/en-us/library/aa364992(v=vs.85).aspx

DWORD WINAPI GetTempPath(
 __in   DWORD nBufferLength,
 __out  LPTSTR lpBuffer
);

所以GetTempPath的定义类似于

GetTempPath(DWORD nBufferLength, LPTSTR& lpBuffer);

什么意思,编译器通过referenece传递值lpBuffer。