Paradox / ObjectPal 和 Microsoft XML Services (MSXML):调用某些方法时崩溃

Posted

技术标签:

【中文标题】Paradox / ObjectPal 和 Microsoft XML Services (MSXML):调用某些方法时崩溃【英文标题】:Paradox / ObjectPal and Microsoft XML Services (MSXML): crashes when calling certain methods 【发布时间】:2013-01-23 07:01:43 【问题描述】:

我使用 Microsoft XML Core Services (MSXML) 来解析和创建带有 Paradox 11.0.0.676 的 XML 文档。

当我调用 oleAuto-objects 的某些方法时,Paradox 在到达 endMethod 语句时崩溃 (代码在按钮的 pushButton 事件中)。这使我得出结论,问题可能是 oleAuto 变量的“释放”。所以我已经把变量声明放到了表单中。如果我调试代码, GPF 不再出现在 Button 的 endMethod 中,但在退出程序时仍会出现。所以我可能是对的,问题在于释放变量。 OLE 对象的显式 close() 命令不能解决问题。有人有想法吗?我真的需要 MSXML 工作 :-( 其他 MSXML 方法工作得很好,比如通过 XPath 搜索 XML 文件以查找特定元素等。

这里是代码和 xml 文件。 该代码根据 xml 模式验证 xml 文件的节点。 (代码和 xml 文件来自 microsoft msxml 参考,稍作改动并应用于 objectpal):

ValidateNode.xml

<?xml version="1.0"?>
<x:books xmlns:x="urn:books">
   <book id="bk001">
      <author>Hightower, Kim</author>
      <title>The First Book</title>
      <genre>Fiction</genre>
      <price>44.95</price>
      <pub_date>2000-10-01</pub_date>
      <review>An amazing story of nothing.</review>
   </book>

   <book id="bk003">
      <author>Nagata, Suanne</author>
      <title>Becoming Somebody</title>
      <genre>Biography</genre>
      <review>A masterpiece of the fine art of gossiping.</review>
   </book>
</x:books>

ValidateNode.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="urn:books"
            xmlns:bks="urn:books">

  <xsd:element name="books" type="bks:BooksForm"/>

  <xsd:complexType name="BooksForm">
    <xsd:sequence>
      <xsd:element name="book"
                  type="bks:BookForm"
                  minOccurs="0"
                  maxOccurs="unbounded"/>
      </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="BookForm">
    <xsd:sequence>
      <xsd:element name="author"   type="xsd:string"/>
      <xsd:element name="title"    type="xsd:string"/>
      <xsd:element name="genre"    type="xsd:string"/>
      <xsd:element name="price"    type="xsd:float" />
      <xsd:element name="pub_date" type="xsd:date" />
      <xsd:element name="review"   type="xsd:string"/>
    </xsd:sequence>
    <xsd:attribute name="id"   type="xsd:string"/>
  </xsd:complexType>
</xsd:schema>

ObjectPal-代码: Paradox-Form 上面只有一个按钮,这是 pushButton 事件的代码(快速和脏代码:-))。 代码按其应有的方式工作:元素显示在消息框中,该消息框详细说明了元素无效的原因。如果我调试代码,Paradox 在到达 endMethod 语句时会崩溃。操作系统是 Windows 7 64 位,Paradox 是版本 11.0.0.676。

method pushButton(var eventInfo Event)
var
 xd, xs, er, nlist, node        oleAuto
 err                            oleAuto
endVar
 if NOT xd.open("Msxml2.DOMDocument.6.0") then
  msgStop("Error", "Error")
  return
 endIf
 if NOT xs.open("Msxml2.XMLSchemaCache.6.0") then
  msgStop("Error", "Error")
  return
 endIf
 xs.add("urn:books", "C:\\LZE\\MSXML\\validateNode.xsd")
 try
  xd^schemas = xs
  xd^async = false
  xd^validateOnParse = false
  xd^load("C:\\LZE\\MSXML\\validateNode.xml")
  err = xd^validate()

  nList = xd^selectNodes("//book")
  node = nList^item(1)
  msgInfo("", node.xml)
  err = xd^validateNode(node)
  msgInfo("", err.reason)

 onFail
  msgStop("!!!", "!!!")
 endTry
 try
  if xd.isAssigned() then
   xd.close()
  endIf
  if xs.isAssigned() then
   xs.close()
  endIf
  if nList.isAssigned() then
   nList.close()
  endIf
  if err.isAssigned() then
   err.close()
  endIf
         onFail
  msgStop("!!!", "!!!")
 endTry

【问题讨论】:

【参考方案1】:

我只是想给你一个简短的总结我遇到的问题和一个修复/解决方法,因为它可能有助于解决其他 activex 和一般保护故障问题:

当调用 activex 对象的某些方法(我的假设是,指针可能是问题)时,悖论崩溃,通常带有一般保护错误。在大多数情况下,这发生在到达 endmethod-statement 之前。这让我想到了一个假设,即问题可能是变量的“取消引用”。 paradox / windows 无法清除它们,或者试图访问内存的某些空间,这被 windows 拒绝。按钮的 pusubutton-event 中的以下代码就是一个很好的例子:

method pushButton(var eventInfo Event)
var
    oXD, oXMLElement    oleAuto
endVar

    if NOT oXD.open("Msxml2.DOMDocument.6.0") then
        msgStop("Error", "cant create object")
        return
    endIf

    oXMLElement = oXD.createElement("someElement")
                msgInfo("", oXMLElement.xml)
    oXD.appendChild(oXMLElement)


endMethod

第一次按下按钮时,会显示消息框,显示创建的 xml 元素。如果您现在从运行模式切换到编辑模式,运行表单并再次按下按钮,悖论崩溃:oleauto 变量 oXMLElement 仍在内存中。 我花了很多时间寻找解决这个问题的方法,终于找到了一个解决方法:在方法结束之前,让 oleauto 变量引用另一个对象,进度条,例如:

if NOT oXMLElement.open("MSComctlLib.ProgCtrl.2") then
    msgStop("Error", "cant create object")
    return
endIf

至少这对我有用,使用 paradox 11,在 win xp 和 win 7 上测试。任何 cmets 都受到欢迎。 :-)

【讨论】:

以上是关于Paradox / ObjectPal 和 Microsoft XML Services (MSXML):调用某些方法时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Paradox (ObjectPal) 应用程序偶尔导致一般保护违规,正在寻找原因

读取 Paradox 数据库文件

Paradox 如何管理 null 和空值?

Paradox 4.5 可以安装在服务器上吗?

Paradox 插入数据操作必须使用可更新查询

是否可以使用 pyodbc 读取在 Paradox gui 中打开的 Paradox 表?