2017-07-08 48 views
0

我有下面的代码,当尝试创建一个新目录时有时会返回错误。有时当该目录不存在时,它会引发错误并且不会创建该目录。我想知道为什么?CreateDir在QB64中抛出异常

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编写的。

+0

当我说“有时”时,我的意思是说有时它不会产生错误。 – eoredson

回答

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 \ t1 \ t2 \ t3如果\ Temp不存在。

+0

因为如果你不这样做,你会得到一个错误0x3这是一个“系统找不到指定的路径。” – eoredson

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 
+0

奇数。我会认为'lpSecurityAttributes'(声明中的'X $')会像'_OFFSET'('X%&'),而不是字符串。 'CHR $(0)'意味着你有一个字符串包含一个值为0的单个字节,所以我将'0%&'传递给函数,产生一个NULL指针。 “CHR $(0)”可能是您“有时”问题的原因。然后再一次,我有一段时间没有使用Windows,所以也许我错了。我很惊讶,还没有一种将各种C/Windows API数据类型映射到QB64类型的资源...... –

+0

所有传递给Windows库的字符串都必须以null结尾。第二个参数中的null是必需的。第一个参数声明一个指向该函数的指针。 – eoredson

+0

我指的是一个NULL指针,而不是以空字符结尾的字符串。 'lpSecurityAttributes'是一个指向结构的指针,而不是一个字符串,但是我之前看过你发布过这类东西,所以也许你知道我不知道的东西。毕竟,我不再与QB64一起工作,所以我说的任何事情都可能是基于生锈的记忆。 :P –

1

什么要传递作为CreateDirectoryAlpSecurityAttributes参数是一个字符串长度为0;字符串仍然有内存地址,这意味着你传递了一个非空指针。这被CreateDirectoryA解释为指向SECURITY_ATTRIBUTES structure的指针,其第一个字节设置为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值的指针(因为除非使用BYVAL关键字;字符串和用户定义类型不能通过BYVAL),否则QB64中的所有内容都会被指针传递。

+0

谢谢!这可能解决了这个问题。竖起大拇指。 – eoredson

+0

而CreateDirectory函数调用指向SECURITY_ATTRIBUTES结构。 SECURITY_ATTRIBUTES结构指向SECURITY_DESCRIPTOR结构。而... – eoredson

+0

一个安全描述符包括: 所有者的安全标识符(SID) 甲主要组SID 随机访问控制列表(DACL) 一种系统,访问控制列表(SACL) – eoredson