我做了个程序,结构是这样子的:
有个Dll做统一的数据连接(ADO)——因为项目不是三层的,只是单机版的
又做了些DLL做为公共的API——这样子就算是把项目划分了,也利于升级
问题就出在这儿!!!
当我在API里到数据库中去取记录并返回数据信息——我是把一条记录的所有字段的值拼成一个串返回的,用的是PChar!当数据表字段超过14个就报错(少于等于14个没事儿)!
调试:
数据库:Access / Sybase
数据连接:ADO
开发:Delphi7
数据集控件:TADOQuery当然换作string返回没事儿,或者在API里New(Result)也不报错但是返回值不完整
为什么?
为什么在Delphi6里我没碰到——原来这个API在D6中调试试通过的!刚升级到D7没想到这出了错!
为什么是14个字段?
为什么?!问题会是什么呢?会不会出现别的错?!

解决方案 »

  1.   

    注:
    数据库:Access / Sybase
    这是我测试过的数据库,为的是看看是不是数据库的原因——当然不是!现在想,也可能是Delphi封装的ADO的事儿!——要是这样可就麻烦了!
      

  2.   

    14个字段估计不是关键,也许是字符的长度超出了范围,比如string被看成了ShortString~~
    关键是找到出错的原因,情况不是很多,你可以分步排查~~
    比如在14个字段的时候在后面再加些字符~~
    如果是空间不够就再分配资源~~
    一步一步来~~
      

  3.   

    伴水大哥好久都没看到你来了
    估计是字符长度,用PWideChar看看吧
      

  4.   

    是呀,是不是编译器的默认设置的问题,以前看过有关d6,d7的区别种种言论,但没有留心,你查查看!比较一下d6,d7的编译语句有区别吗等等
      

  5.   

    同意 zswang(伴水清清)(专家门诊清洁工)
      

  6.   

    跟字符长度应该么关系吧?!还有我用BDE测试也有问题!
    看来不是ADO组件的事儿!
    难道真的是D7对内存管理的问题?!——那不知道还会在什么地方出错!怎么办?
      

  7.   

    tongki_8(矛盾与迟钝) :
    “你的DLL应重新审视”?
    你做的DLL没问题吗?是在D7下做的吗?说详细点儿ok?
      

  8.   

    晕~跟字段数目好像没关系~!
    我试了其他的表,有的只能13个有的可以很多~~~~难道是我的DLL的构架错啦?
    不可能吧~大家在DLL里做数据库访问操作是怎么做的?
      

  9.   

    你预先分配的返回PCHAR的长度是多大呢?
      

  10.   

    如果不做“统一”的数据连接的那个DLL——直接在DLL的窗体中做数据连接做操作,好像没问题!
    ?!?!
    郁闷~还有,只要做ShowMessage就没错!为什么?什么原因?!
      

  11.   

    outer2000(天外流星) :
    我可以预先分配返回值PChar的Size,可怎么释放呢?
      

  12.   

    PWideChar?没用过~
    怎么用?请指教~
      

  13.   

    pchar()最大返回值可能有问题.
      

  14.   

    可能是类型的问题(PCHAR),
    你可能这样计算一下:
    你原来测试时的14个字段宽度加起来占多少字节????
    你有的只13个字段,宽度加起来占多少字节????
    有的很多,宽度加起来占多少字节????
    计算一下,比较一下,
    可能是PCHAR类型限制了返回字段的个数!!!!如果说错了,别怪我
      

  15.   

    zswang(伴水清清)(专家门诊清洁工) 其实是个MM,知道么?照片看起来好性感。。O&3$
      

  16.   

    解决方案:Build with Runtime Packages为什么?
    Delphi中很多“解决不了”的问题只要使用就可以解决?我遇到的类似问题还有:
    在DLL做MDIChild窗体,无法获得ActiveMDIChild,使用“Build with Runtime Packages”编译即可!为什么?!
      

  17.   

    看帮助获知:
    String to PChar conversionsDelphi6中:
    Long string to PChar conversions are not automatic. Some of the differences between strings and PChars can make conversions problematic:Long strings are reference-counted, while PChars are not.
    Assigning to a string copies the data, while a PChar is a pointer to memory.
    Long strings are null-terminated and also contain the length of the string, while PChars are simply null-terminated.Situations in which these differences can cause subtle errors are discussed in this section.Delphi7中:
    Long string to PChar conversions are not automatic. Some of the differences between strings and PChars can make conversions problematic:Long strings are reference-counted, while PChars are not.
    Assigning to a string copies the data, while a PChar is a pointer to memory.
    Long strings are null-terminated and also contain the length of the string, while PChars are simply null-terminated.Situations in which these differences can cause subtle errors are discussed in the following topics:String dependencies 
    Returning a PChar local variable 
    Passing a local variable as a PChar 多了三个连接:
    String dependencies 
    Returning a PChar local variable 
    Passing a local variable as a PChar 
    其中 Returning a PChar local variable 写道:
    A common error when working with PChars is to store a local variable in a data structure, or return it as a value. When your routine ends, the PChar disappears because it is a pointer to memory, and not a reference counted copy of the string. For example:function title(n: Integer): PChar;
    var
      s: string;
    begin
      s := Format('title - %d', [n]);
      Result := PChar(s); // DON'T DO THIS
    end;This example returns a pointer to string data that is freed when the title function returns.DON'T DO THIS!!!Delphi不让这么做啦~!?!在帮助 Passing a local variable as a PChar 中讲道:
    Consider the case where you have a local string variable that you need to initialize by calling a function that takes a PChar. One approach is to create a local array of char and pass it to the function, then assign that variable to the string:// assume FillBuffer is a predefined function
    function FillBuffer(Buf:PChar;Count:Integer):Integer
    begin
      . . .
    end;
    // assume MAX_SIZE is a predefined constant
    var
      i: Integer;
      buf: array[0..MAX_SIZE] of char;
      S: string;
    begin
      i := FillBuffer(0, buf, SizeOf(buf)); // treats buf as a PChar
      S := buf;
      //statements
    end;This approach is useful if the size of the buffer is relatively small, since it is allocated on the stack. It is also safe, since the conversion between an array of char and a string is automatic. The Length of the string is automatically set to the right value after assigning buf to the string.To eliminate the overhead of copying the buffer, you can cast the string to a PChar (if you are certain that the routine does not need the PChar to remain in memory). However, synchronizing the length of the string does not happen automatically, as it does when you assign an array of char to a string. You should reset the string Length so that it reflects the actual width of the string. If you are using a function that returns the number of bytes copied, you can do this safely with one line of code:var
      S: string;
    begin
      SetLength(S, MAX_SIZE; // when casting to a PChar, be sure the string is not empty
      SetLength(S, GetModuleFilename( 0, PChar(S), Length(S) ) );
      // statements
    end;我考~ 
    真烦~
    函数结构改起来非搞死我不可了!
    郁闷~