首页
社区
课程
招聘
请教C++Build编译器相关配置(For DLL)?[求助]
发表于: 2007-1-28 15:35 5494

请教C++Build编译器相关配置(For DLL)?[求助]

2007-1-28 15:35
5494
我使用Borland C++5.5 命令行编译器原意要 编译出 stdcall 输出函数的DLL供调用,使用中发现会破坏我调用函数前的数据,到底哪搞错了?请帮忙看一下。

参数使用如下:
// BCC32.EXE 为编译器
C:\BCC55\BIN\BCC32.EXE  -I"C:\BCC55\Include" -L"C:\BCC55\Lib" -O1 -WD -3 "C:\delphi\vc\assembl.c" -n"C:\delphi\vc"

delphi单元使用关键如下:
implementation
//////////////////// ASSEMBLER, DISASSEMBLER AND EXPRESSIONS ///////////////////
const
MAXCMDSIZE  =   16;              // Maximal length of 80x86 command
MAXCALSIZE  =   8;               // Max length of CALL without prefixes
NMODELS    =    8;               // Number of assembler search models
TEXTLEN   =     255;             // Maximal length of text string
asmdll = 'assembl.dll';

type
  TAsmModel = packed record           // Model to search for assembler command
    code:array[0..MAXCMDSIZE-1] of byte;   // Binary code
    mask:array[0..MAXCMDSIZE-1] of byte;   // Mask for binary code (0: bit ignored)
    length:SmallInt;               // Length of code, bytes (0: empty)
    jmpsize:SmallInt;              // Offset size if relative jump
    jmpoffset:SmallInt;            // Offset relative to IP
    jmppos:SmallInt;               // Position of jump offset in command
  end;
  PAsmModel = ^TAsmModel;

//DLL函数声明
function  AssembleCode(Cmd: PChar; IP: DWORD; Model: PAsmModel; Attempt: Integer;
  ConstSize: Integer; ErrText: PChar):Integer; Stdcall; external asmdll;

//调用
procedure TForm1.BnClick(Sender: PObj);
var
  myModel: TAsmModel;
  s : PChar;
  Input : String;
  TmpStr, ErrBuf : array[0..TEXTLEN] of Char;
  i: Integer;
begin
  if EB1.Text <> '' then
  begin
    FillChar(TmpStr, TEXTLEN, 0);
    FillChar(myModel, SizeOf(myModel), 0);
    s := @TmpStr[0];
    Input := EB1^.Text;
    for i:=1 to Length(Input) do begin
      s^ := Input[i];
      inc(s);
      if i>TEXTLEN then break;
    end;

    AssembleCode(@TmpStr[0], $401000, @myModel, 0, 0, @ErrBuf[0] );

    Input := ''; //函数出来后,Input已经变了
    EB2.Clear ; //指针也变错了
    if myModel.length >0 then
    begin
      for i:=1 to myModel.length do
        Input := Input + Format('%s', [myModel.code[i]] );
      EB2.Text := Input;
    end
    else
       EB2^.Text := ErrBuf;
  end;
end;

附编译文件

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
2
const
MAXCMDSIZE  =   16;              // Maximal length of 80x86 command
MAXCALSIZE  =   8;               // Max length of CALL without prefixes
NMODELS    =    8;               // Number of assembler search models
TEXTLEN   =     255;             // Maximal length of text string
asmdll = 'assembl.dll';

type
  TAsmModel = packed record           // Model to search for assembler command
    code:array[0..MAXCMDSIZE-1] of byte;   // Binary code
    mask:array[0..MAXCMDSIZE-1] of byte;   // Mask for binary code (0: bit ignored)
//下面的变量溢出了,将下面的SmallInt改成Integer即可。
    length:SmallInt;               // Length of code, bytes (0: empty)
    jmpsize:SmallInt;              // Offset size if relative jump
    jmpoffset:SmallInt;            // Offset relative to IP
    jmppos:SmallInt;               // Position of jump offset in command

  end;
  PAsmModel = ^TAsmModel;

//DLL函数声明
function  AssembleCode(Cmd: PChar; IP: DWORD; Model: PAsmModel; Attempt: Integer;
  ConstSize: Integer; ErrText: PChar):Integer; Stdcall; external asmdll;

//调用
procedure TForm1.BnClick(Sender: PObj);
var
  myModel: TAsmModel;
  s : PChar;
  Input : String;
  TmpStr, ErrBuf : array[0..TEXTLEN] of Char;
  i: Integer;
begin
  if EB1.Text <> '' then
  begin
    FillChar(TmpStr, TEXTLEN, 0); //将TEXTLEN改成TEXTLEN+1
    FillChar(myModel, SizeOf(myModel), 0);
    s := @TmpStr[0];
    Input := EB1^.Text; //EB1^.Text??,Edit控件可以这样用指针访问吗?你的是Delphi几?
    for i:=1 to Length(Input) do begin
      s^ := Input[i];
      inc(s);
      if i>TEXTLEN then break;
    end;

    AssembleCode(@TmpStr[0], $401000, @myModel, 0, 0, @ErrBuf[0] );

    Input := ''; //函数出来后,Input已经变了
    EB2.Clear ; //指针也变错了
    if myModel.length >0 then
    begin
      for i:=1 to myModel.length do
        Input := Input + Format('%s', [myModel.code[i]] ); //'%s'的格式不能用于Byte的类型,应该用'%x'的参数才对,或者使用强制类型转换char(myModel.code[i])
      EB2.Text := Input;
    end
    else
       EB2^.Text := ErrBuf; //EB2^.Text??,Edit控件可以这样用指针访问吗?你的是Delphi几?
  end;
end;

PS:不要点将,呵
2007-1-29 13:18
0
雪    币: 260
活跃值: (81)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
看雪老大也说不能点将的
2007-1-29 13:44
0
雪    币: 243
活跃值: (160)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
最初由 小虾 发布
const
MAXCMDSIZE = 16; // Maximal length of 80x86 command
MAXCALSIZE = 8; // Max length of CALL without prefixes
NMODELS = 8; // Number of assembler search models
TEXTLEN = 255; // Maximal length of text string
........


“PS:不要点将”,帖子标题吧,如果是不好意思,以后注意不会这样的!

这里还是要谢谢小虾,嗯,我是用DelphiKOL(“Sender: PObj”这个最明显),怕看不懂,匆忙中改回到Delphi中丢三落四了(没改好),KOL所有的控件都是控件指针(KOL是没问题的),Format临时改的(乱来了),KOL我是用 Int2Hex(value, dispNum)代替Format这个。关键被你点出来了,原来不是DLL有问题(对C不熟悉),“变量溢出”,在C里面 int 类型应该等价于 Delphi 的 SmallInt,我原本这个TAsmModel定义的结构大小和C 定义的一样,Integer替换SmallInt后没错是解决了变量溢出,但这明摆着使Delphi定义的结构比C使用的要大,你会发现返回的TAsmModel所有成员跟期代的是不一样的,不知你怎么看...
2007-1-29 14:50
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
5
int是未标准定义的类型,在不同的编辑器不同的平台上他代表者不同的位长。所以他的长度不一定是16位的,在32位的平台上也可以是32位的。你那个C文件我没有BC++编辑器,我是用VC++编译的。经过下面的测试可以看出C的int和Delphi的SmallInt的位长是不等的。C的int是32位,而SmallInt是16位的。不过BC++中的int是不是16位的我就不太清楚了。你可以在BC++中用sizeof(int)测试看看,是16位的还是32位的。
VC++中 sizeof(int) == 4
Delphi中 sizeof(SmallInt) = 2
Delphi中 sizeof(Integer) = 4
2007-1-29 16:47
0
游客
登录 | 注册 方可回帖
返回
//