Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 协调错误:是否有人对截断的错误消息有问题?_Delphi_Datasnap_Tclientdataset - Fatal编程技术网

Delphi 协调错误:是否有人对截断的错误消息有问题?

Delphi 协调错误:是否有人对截断的错误消息有问题?,delphi,datasnap,tclientdataset,Delphi,Datasnap,Tclientdataset,我又来这里向你求助了。这一次,我相信很少有人会回应,因为我将讲述的问题非常特殊。我从DataSnap的世界开始,仍然有一些事情我不明白我将如何关联这个错误 我的Delphi是XE(版本1,更新1)。我使用Postgres生成葡萄牙语(葡萄牙语-巴西)的错误消息,因此错误消息带有重音。连接组件是ZeosLib软件包 我正在使用一个对话框“协调错误”来显示应用更新时产生的错误,并且为了测试,我尝试插入一条已经存在的记录,从而违反了唯一键,从而显示了协调错误对话框 在对话框的备忘录中,出现的消息被截断

我又来这里向你求助了。这一次,我相信很少有人会回应,因为我将讲述的问题非常特殊。我从DataSnap的世界开始,仍然有一些事情我不明白我将如何关联这个错误

我的Delphi是XE(版本1,更新1)。我使用Postgres生成葡萄牙语(葡萄牙语-巴西)的错误消息,因此错误消息带有重音。连接组件是ZeosLib软件包

我正在使用一个对话框“协调错误”来显示应用更新时产生的错误,并且为了测试,我尝试插入一条已经存在的记录,从而违反了唯一键,从而显示了协调错误对话框

在对话框的备忘录中,出现的消息被截断。请查看:

ERRO:  duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"
DETAIL:  Chave (va_login)=(admin) já existe.
CONTEXT:  comando SQL "INSERT INTO USUARIOS (VA_NOME
                           ,VA_LOGIN
                           ,CH
但实际上应该返还的是:

ERRO:  duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"
DETAIL:  Chave (va_login)=(admin) já existe.
CONTEXT:  comando SQL "INSERT INTO USUARIOS (VA_NOME
                               ,VA_LOGIN
                               ,CH_SENHA
                               ,VA_EMAIL)
                        VALUES (pVA_NOME
                               ,pVA_LOGIN
                               ,pCH_SENHA
                               ,pVA_EMAIL)"
    PL/pgSQL function "idu_usuarios" line 7 at comando SQL
我已经在服务器上进行了调试,以查看问题是否是ZeosLib,但是我发现在服务器上生成的错误消息是完整的,证明ZeosLib没有截断消息。一切都是unicode。在我的程序和ZeosLib中,所有字符串都是WideString(默认值)

如您所知,要在服务器上引发异常,通常通过DataSnap将异常转发到客户端,在客户端,TClientDataSet的协调方法验证是否存在问题,然后引发著名的异常EReconcileError,该异常可以在TClientDataSet的OnReconcileError事件中处理,因此,我认为消息正在被DataSnap截断

在客户机上,我调试协调方法(DBClient.pas),在抛出异常之前,流立即进入cpp源代码中的一个函数,我认为该函数是库midas.dll的一部分,更具体地说,是MidasLib.obj,因为我使用的是这种策略,所以不必将dll与我的应用程序一起分发

Check(FDSBase.Reconcile_MD(FReconcileDataSet.FDSBase, FDeltaPacket, VarToDataPacket(Results), Integer(Self), RCB));
此调用在Delphi XE Update1上的单元DBClient.pas的第1952行完成。按F7,调试器进入源C++(CPP),因此我相信它在MIDASLI.OBJ中。我怎么不明白C++,我按下SHIFT-F8退出当前方法,并返回下一个指令,这已经在事件内部的RealError!!!因此,截断必须在我提到的函数中完成,在cpp源中,在midaslib中

我的目的是使“协调错误”对话框不仅成为最终用户的工具,而且还支持个人,分别提供错误、详细信息和上下文信息。这对发现问题有很大帮助

现在的问题是使消息完整显示。有没有人在邮件被midas截断时遇到过这种问题

另一点是DSClient.pas我可以在将错误消息传递给异常时提取错误消息:

'Erro SQL: ERRO:  duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"'#$A'DETAIL:  Chave (va_login)=(admin) já existe.'#$A'CONTEXT:  comando SQL "INSERT INTO USUARIOS (VA_NOME'#$A'                           ,VA_LOGIN'#$A'                           ,CH'
如果删除引号并用空格(一个字符)替换#$A(1个字符),您将看到字符串正好包含255个字符

我还发现dspickle.cpp中的“GetErrorString”使用常量DBIMAXMSGLEN,它在bdetypes.h中定义为127(255的一半)。正如我们在Unicode世界中一样,将该值增加到255以使每个字符有两个字节不是一个问题吗?这只是一个猜测

我把问题留给大家,因为我缺乏理解C++的知识:谁能帮助,只需看看DSPICLE .CPP中的函数实现“GETError Stand”。这是:

LoadString((HINSTANCE)hDll, iErrCode, pString, DBIMAXMSGLEN)

pString是错误消息,DBIMAXMSGLEN=127。

与其他人的观点相矛盾,我决定进一步调整,最终找到了增加“协调”错误消息中字符数的方法。正如我所想,问题出在midas.dll中,或者更具体地说是组成midas dll的源代码中,因为同一组源代码可以创建MidasLib,而不需要midas dll。为了解决这个问题,我必须安装Delphi C++的个性来编译MIDAS。 在找到错误线后,我发现甚至有一个QC()的维修请求,这似乎被Embarcadero的工作人员忽略了,因为“解决方案”是“推迟到下一版本”(推迟到下一版本)但是这个请求是从2010年开始的,我使用的是Delphi XE,我认为它应该有解决方案,但这里我自己更正;)

问题出在“DSBASE”类的方法“Clone”中,源代码“ds.cpp”中的第2133行(Delphi XE,Update1)。下面是代码块。红线是有问题的一条线:

// Set the third field for the error string.
LdStrCpy((pCHAR)pFldDes->szName, szdsERRMESSAGE);
pFldDes->iFldType = fldZSTRING;
pFldDes->iUnits1 = 255; // Increased on request.. DBIMAXMSGLEN;
pFldDes++;
请注意,问题行非常有趣。它的常量值为255,这限制了错误消息的大小和注释“根据请求增加”。还要注意,在注释旁边,有一个常量
DBIMAXMSGLEN
,我已经发现并怀疑它是导致问题的原因,但由于没有使用它,我更改了
DBIMAXMSGLEN
的值,但错误消息始终没有更改。值得一提的是,
DBIMAXMSGLEN
后面有一个分号(;),这让我想到,在这之前(我不知道什么时候),这一行是我修复之后的一行:

pFldDes->iUnits1 = DBIMAXMSGLEN;
这就好像有人故意将字段值设置为255,删除了以前的实现,该实现实际上是动态的,而且看起来更正确。执行行I的替换后,将
DBIMAXMSGLEN
的值增加到1024
DBIMAXMSGLEN
被声明为“bdetypes.h”作为定义。修正后的线路是这样的:

#define DBIMAXMSGLEN         1024           // Max message len
在“ds.cpp”和“bdetypes.h”中进行了这两个更改之后,我构建、测试并获得了预期的结果:在协调对话框中完整显示了错误消息

对于那些想尝试解决这个问题的勇敢者,如果我没记错的话,你需要MIDAS的源代码,它来自2010年的Delphi。好的,我