0

我有以下代码在尝试创建新目录时有时会返回错误。有时,当该目录不存在时,它会引发错误并且不会创建该目录。我想知道为什么?

DECLARE DYNAMIC LIBRARY "kernel32"
    FUNCTION CreateDirectoryA% (F$, X$)
    FUNCTION GetLastError& ()
END DECLARE
F$ = "TEMPX" + CHR$(0) ' new directory to create
x = CreateDirectoryA(F$, CHR$(0))
IF x = 0 THEN
    IF GetLastError = &H3E6 THEN
        PRINT "Invalid access to memory location."
    END IF
END IF

这段代码是用 QB64 编写的。

4

3 回答 3

1

您作为lpSecurityAttributes参数传递的CreateDirectoryA是长度为 0 的字符串;字符串仍然具有内存地址,这意味着您正在传递一个非空指针。这被 CreateDirectoryA 解释为指向SECURITY_ATTRIBUTES 结构的指针,其第一个字节设置为 0。结构中的其余字节是您尚未初始化的内存,这意味着结构nLength在小端机器上的第一个字段可能类似于0xFFFFFF00,即 4294967040 — 无效大小。该lpSecurityDescriptor结构的字段可能也充满了字节(您的程序可能可以访问,但可能无法访问),因此这也可能导致问题。

您可以轻松解决此问题:

' X%& may also be written X AS _OFFSET.
FUNCTION CreateDirectoryA% (F$, BYVAL X%&)

...

x = CreateDirectoryA(F$, 0)

这导致NULL正确传递指针。关键字是必需的BYVAL,否则您将传递一个指向该_OFFSET值的指针(因为 QB64 中的所有内容都是通过指针传递的,除非您使用BYVAL关键字;字符串和用户定义的类型不能传递BYVAL)。

于 2017-07-11T02:31:49.063 回答
0

当异常 x3E6 发生时,此代码强制创建目录,但确实解释了为什么首先发生错误:

DECLARE DYNAMIC LIBRARY "kernel32"
    FUNCTION CreateDirectoryA% (F$, X$)
    FUNCTION GetLastError& ()
END DECLARE
DO
    F$ = "TEMPX" + CHR$(0) ' new directory to create
    x = CreateDirectoryA(F$, CHR$(0))
    IF x THEN ' successful create
        EXIT DO
    END IF
    IF x = 0 THEN
        REM Test for Invalid access to memory location.
        IF GetLastError = &H3E6 THEN
            _DELAY .2
        ELSE
            EXIT DO
        END IF
    END IF
LOOP
于 2017-07-08T05:36:36.127 回答
0

然后我遇到了在路径中创建子目录的问题,所以我写了这个:

DECLARE DYNAMIC LIBRARY "kernel32"
    FUNCTION CreateDirectoryA% (F$, BYVAL X&&)
    FUNCTION GetLastError& ()
END DECLARE
DO ' get directory
    PRINT "Dir";: INPUT Directory$
    IF Directory$ = "" THEN END
    GOSUB CreateDir
LOOP
END
CreateDir:
' construct path
Directory$ = RTRIM$(Directory$)
IF RIGHT$(Directory$, 1) <> "\" THEN
    Directory$ = Directory$ + "\"
END IF
' create path
x = 0
Next.Dir = INSTR(Directory$, "\")
DO
    IF Next.Dir = False THEN
        EXIT DO
    END IF
    SubDir$ = LEFT$(Directory$, Next.Dir - 1) ' \tempx\t1\t2\t3\
    Next.Dir = INSTR(Next.Dir + 1, Directory$, "\")
    ' make directory name
    IF LEN(SubDir$) THEN
        ' create directory
        f$ = SubDir$ + CHR$(0)
        x = CreateDirectoryA(f$, 0)
        ' check error
        IF x = 0 THEN
            IF GetLastError& = &HB7 THEN ' ignore already exists
                ' nul
            ELSE
                EXIT DO
            END IF
        END IF
    END IF
LOOP
IF x = 0 THEN
    PRINT "Error x"; HEX$(GetLastError&)
ELSE
    PRINT "Directory created."
END IF
RETURN

这样,如果您指定一个不存在的路径,它将创建整个路径名。例如,如果 \Temp 不存在,则为 \Temp\t1\t2\t3。

于 2017-07-18T04:17:15.917 回答