C 代码编译成 DLL 文件后, 执行结果与 Delphi 的 DLL 结果不一样.
代码如下:///////////////////////////////////////////////
//
//  Delphi 代码
//
///////////////////////////////////////////////
const
  constACMAdptive: array[0..15] of SmallInt = (230, 230, 230, 230, 307, 409,
                   512, 614, 768, 614, 512, 409, 307, 230, 230, 230);  constACMCoef: array[0..1, 0..6] of SmallInt = (
                (256, 512,  0, 192, 240, 460, 392),
                (0,   -256, 0, 64,  0,   -208, -232));procedure CreateACMData(Source: array of Byte; var Dest: array of SmallInt);
var
  i, j, Prec: Integer;
  Sample, Delta: LongInt;
  Samp1, Samp2: SmallInt;
  Code: Byte;
begin
  Prec := Source[0];
  Delta := (Source[2] shl 8) or Source[1];
  Samp1 := (Source[4] shl 8) or Source[3];
  Samp2 := (Source[6] shl 8) or Source[5];
  Dest[0] := Samp2;
  Dest[1] := Samp1;
  
  for i := 0 to 248 do
  begin
    for j := 0 to 1 do
    begin
      if j = 0 then
      begin
        Code :=(Source[i + 7] and $0F0);
        Code := Code shr 4;
      end
      else begin
        Code := Source[i + 7] and $0F;
      end;      Sample := (Samp1 * constACMCoef[0, Prec] + Samp2 *
                 constACMCoef[1, Prec]) div 256;
      if (Code > 7) then
      begin
        Sample := Sample + Delta * (Code - $10);
      end
      else begin
        Sample := Sample + Delta * Code;
      end;      if Sample > 32767 then
      begin
        Sample := 32767;
      end;      if Sample < -32768 then
      begin
        Sample := -32768;
      end;      Dest[i * 2 + j + 2] := Sample;
      Delta := (Delta * constACMAdptive[Code]) div 256;      if Delta < 16 then
      begin
        Delta := 16;
      end;      Samp2 := Samp1;
      Samp1 := Sample;
    end;
  end;
end;
///////////////////////////////////////////////
//
//  C 代码
//
///////////////////////////////////////////////
  short constACMAdptive[16] = {230, 230, 230, 230, 307, 409,
                   512, 614, 768, 614, 512, 409, 307, 230, 230, 230};  short constACMCoef[2][7] = {
  {256, 512,  0, 192, 240, 460, 392},
  {0,   -256, 0, 64,  0,   -208, -232}};void WINAPI CreateACMData(byte *Source, short *Dest)
{
int i, j, Prec;
LONG Sample, Delta;
short Samp1, Samp2;
byte Code; Prec = Source[0];
Delta = (Source[2] << 8) | Source[1];
Samp1 = (Source[4] << 8) | Source[3];
Samp2 = (Source[6] << 8) | Source[5];
Dest[0] = Samp2;
Dest[1] = Samp1;
  
for (i = 0; i <= 248; i++)
{
for (j = 0; j <= 1; j++)
{
Code   = (j==0) ? ((Source[i + 7] & 0xF0) >> 4) : (Source[i + 7] & 0x0F);
Sample = (Samp1 * constACMCoef[0][Prec] + Samp2 * constACMCoef[1][Prec]) / 256;
Sample = (Code > 7) ? (Sample + Delta * (Code - 0x10)) : (Sample + Delta * Code);
Sample = (Sample > 32767) ? 32767 : Sample;
Sample = (Sample < -32768) ? -32768 : Sample;
Dest[i * 2 + j + 2] = (byte)Sample;
Delta = (Delta * constACMAdptive[Code]) / 256;
Delta = (Delta < 16) ? 16 : Delta;
Samp2 = Samp1;
Samp1 = (short)Sample;
}

}

解决方案 »

  1.   

    procedure CreateACMData(Source: array of Byte; var Dest: array of SmallInt);
    void WINAPI CreateACMData(byte *Source, short *Dest)// 还是用
    procedure CreateACMData(Source:PByte; Dest:PShort);stdcall; 吧。。里面 用一个指针 指向其首地址 然后移动即可 
      

  2.   

    beyondtkl(大龙驹<*飞的更高*>) 还同明白我的意思??
    如何引用已经没问题. 这一点是肯定.只是内部代码哪里出了问题我却一直找不到.
      

  3.   

    Prec = Source[0];
    ...
    Sample = (Samp1 * constACMCoef[0][Prec] + Samp2 * constACMCoef[1][Prec]) / 256;这样的代码什么意思?你传入的Source[0]如果大过原来的数组边界,那么
    constACMCoef[1][Prec]
    constACMCoef[0][Prec]
    这2个是什么东西来的,根本就乱了么,我设置了断点一看sample的值都不一样了,以后怎么可能一样
    我测试的数组Source[0]=230;
    所以不知道是你的测试的东西都很小还是什么?
    你设置断点一步一步跟踪下去就知道了,看看那里的值不一样
      

  4.   

    我觉得问题可能出在C的位移操作与Delphi的不同上。因为楼主的代码本身存在着一个编译器有关的问题,就是这些的语句:
      Delta := (Source[2] shl 8) or Source[1];
      Samp1 := (Source[4] shl 8) or Source[3];
      Samp2 := (Source[6] shl 8) or Source[5];这里的Source是array of Byte, 既然是Byte,那么shl 8结果应该是什么呢?是0?还是因为最终的值是赋给了LongInt或者SmallInt而不是0呢?换成C之后是不是还是这样的结果呢?我想这个没有特定的答案,这个要取决于用什么样的编译器了。建议楼主改成:
      Delta := Source[2];
      Delta := (Delta shl 8) or Source[1];
      Samp1 := Source[4];
      Samp1 := (Samp1 shl 8) or Source[3];
      Samp2 := Source[6];
      Samp2 := (Samp2 shl 8) or Source[5];
      

  5.   

    Delphi 的代码绝对没有问题, 这是已经通过的成熟代码.
    现在要做的是把它转换为CTO constantine(飘遥的安吉儿)constACMCoef  是一个常量二维数组.
    传入的参数 
    byte *Source, short *DestSource 是一个指向数组首地址的指针.
    并且, Source 里的值都是很小的... 此函数的调用如下.( 已经固定的模式的 )byte Source[256];
    short Dest[500];从一个文件中读取256个值放入Source中CreateACMData(&Source, &Dest);
      

  6.   

    呵呵,谢谢你的提醒。这是以后的任务
    现在最主要的是转换到C语言。至于值的大小,这一点不用担心。
    这其实是一个解压缩的代码压缩比为4:1(ADPCM)一个byte数值它保存了两个压缩后的数据,所以,并且每4位中就有一位是符号位,
    所以不用担心越界。之所以不改用其它的算法,是因为我们的硬件不能改写。
    我的QQ是33591840
    明天一起交流
    我现在不行。 还有其它很重要的事,并且不在自己的电脑。
    非常感谢关注
      

  7.   

    此函数的调用如下.( 已经固定的模式的 )byte Source[256];
    short Dest[500];从一个文件中读取256个值放入Source中CreateACMData(&Source, &Dest);------------>
    不对吧Source就是首地址了Source == &Source[0]; 看看 是不是这个错误?
      

  8.   

    传入的时候把数组名字传入就可以了,数组名就是数组的指针,指向其其实地址
    CreateACMData(Source, Dest);
    这样就可以了
      

  9.   

    没有帮忙,,, 自己搞乎三天搞定... 
    得谢谢 constantine(飘遥的安吉儿) 提醒:  设置断点一步一步执行.( 我以前从来不进行单步执行程序来调试程序,觉得太要时间,
    现在发现这样也好处多多. )也同时贴出代码
    void WINAPI CreateACMData(byte *Source, short *Dest)
    {
    int i, j, Prec;
    LONG Sample, Delta;
    short Samp1, Samp2;
    byte Code; Prec = Source[0];
    Delta = (Source[2] << 8) | Source[1];
    Samp1 = (Source[4] << 8) | Source[3];
    Samp2 = (Source[6] << 8) | Source[5];
    Dest[0] = Samp2;
    Dest[1] = Samp1;
      
    for (i = 0; i <= 248; i++)
    {
    for (j = 0; j <= 1; j++)
    {
    Code   = (j==0) ? ((Source[i + 7] & 0xF0) >> 4) : (Source[i + 7] & 0x0F);
    Sample = (Samp1 * constACMCoef[0][Prec] + Samp2 * constACMCoef[1][Prec]) / 256;
    Sample = (Code > 7) ? (Sample + Delta * (Code - 0x10)) : (Sample + Delta * Code);
    Sample = (Sample > 32767) ? 32767 : Sample;
    Sample = (Sample < -32768) ? -32768 : Sample;
    Dest[i * 2 + j + 2] = (short)Sample;
    Delta = (Delta * constACMAdptive[Code]) / 256;
    Delta = (Delta < 16) ? 16 : Delta;
    Samp2 = Samp1;
    Samp1 = (short)Sample;
    }

    }出错在: 
    Dest[i * 2 + j + 2] = (byte)Sample;正确:
    Dest[i * 2 + j + 2] = (short)Sample;这时粗心所造成. 但是这个贴子也值.
    因为我用单步调试解决了另一个很头痛复杂问题.
    呵呵.希望各位写代码不要粗心... 不然, 你会很痛苦D...
    :)