.h文件向Delphi转换问题及DLL中的函数调用出错(100分)

  • 主题发起人 netCobra
  • 开始时间
N

netCobra

Unregistered / Unconfirmed
GUEST, unregistred user!
.h文件向Delphi转换问题及DLL中的函数调用出错

Sybase SQL Anywhere 数据库提供了一些数据库编程接口,在帮助中这些接口的定义是用C写的,我现在改用Delphi来调用,却怎么也成功不了,每次到调用这个接口的时候就发生异常:Access violation at address xxxxxxxx.Read of address xxxxxxxx,各位富翁们帮忙看看,到底我哪里错了,谢谢!

.h文件中定义如下:

#define a_bit_field unsigned int

typedef struct a_backup_db {
unsigned short version;
const char _fd_ *output_dir;
const char _fd_ *connectparms; // userid,password,database
const char _fd_ *startline; // (NULL for default start line)
MSG_CALLBACK confirmrtn;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
a_bit_field backup_database : 1;
a_bit_field backup_logfile : 1;
a_bit_field backup_writefile: 1; // only if using write file
a_bit_field no_confirm : 1;
a_bit_field quiet : 1;
a_bit_field rename_log : 1;
a_bit_field truncate_log : 1;
a_bit_field rename_local_log: 1;
const char _fd_ *hotlog_filename;
char backup_interrupted;
} a_backup_db;

extern _crtn short _entry DBBackup( const a_backup_db _fd_ * );

其中定义为MSG_CALLBACK的是一些回调函数,用于函数执行过程中的错误处理和信息显示,我翻译成Pascal后如下,执行时出错,请大家帮我看看哪里出问题了,谢谢!

interface

uses windows;
//.......;

type

//.......

//回调函数定义
TMsg_CallBack = function(const x : PChar) : SmallInt; stdcall;

//备份数据库所需的结构
TBackupInfo = packed record
version : Word;
output_dir : PChar;
connectparms : PChar;
startline : PChar;
confirmrtn : TMsg_CallBack;
errorrtn : TMsg_CallBack;
msgrtn : TMsg_CallBack;
statusrtn : TMsg_CallBack;
BACKUP_DATABASE : Byte;
BACKUP_LOGFILE : Byte;
BACKUP_WRITEFILE : Byte;
NO_CONFIRM : Byte;
QUIET : Byte;
RENAME_LOG : Byte;
TRUNCATE_LOG : Byte;
RENAME_LOCAL_LOG : Byte;
hotlog_filename : PChar;
backup_interrupted : char;
end;

//指向TBackupInfo类型的指针
PBackupInfo = ^TBackupInfo;

//.......

end;

implementation

//回调函数定义
function ConfirmRtn(const question : PChar) : ShortInt;stdcall;
function ErrorRtn(const errorstr : PChar) : ShortInt;stdcall;
function MessageRtn(const messagestr : PChar) : ShortInt;stdcall;
function StatusRtn(const statusstr : PChar) : ShortInt;stdcall;

function DBBackup(const DBBackupInfo : PBackupInfo) : SmallInt; far; external 'DBTool8.dll';

//.......

procedure TfrmBackup.btnBackupClick(Sender : TObject);
var
BackupInfo : TBackupInfo;
PointerBackupInfo :pBackupInfo;
begin

//.......

//备份数据库
with BackupInfo do
begin
version := 8020;
output_dir := 'c:/app/backup';
connectparms := 'dsn=appdb;uid=dba;pwd=sql';
startline := nil; //启动行置为null,备份时使用默认的数据库启动行
confirmrtn := ConfirmRtn;
errorrtn := ErrorRtn;
msgrtn := MsgRtn;
statusrtn := StatusRtn;
backup_database := 1;
backup_logfile := 1;
backup_writefile := 1;
no_confirm := 1;
quiet := 0;
rename_log := 0;
truncate_log := 0;
rename_local_log := 0;
hotlog_filename := 'c:/app/appdb.log';
//backup_interrupted := '1';
end;
PointerBackupInfo := @BackupInfo;
try
DBBackup(PointerBackupInfo); //每次执行到这一句时就发生异常:Access violation at
// address xxxxxxxx.Read of address xxxxxxxx
except
on E : exception do
begin
Application.MessageBox(PChar(E.Message), '错误', MB_OK + MB_ICONSTOP);
end;
end;

//........
end;

end;
 
J

JamesBond_L

Unregistered / Unconfirmed
GUEST, unregistred user!
//备份数据库
with BackupInfo do
begin
version := 8020;
output_dir := 'c:/app/backup';
connectparms := 'dsn=appdb;uid=dba;pwd=sql';
startline := nil; //启动行置为null,备份时使用默认的数据库启动行
confirmrtn := ConfirmRtn;
errorrtn := ErrorRtn;
msgrtn := MsgRtn;
statusrtn := StatusRtn;
backup_database := 1;
backup_logfile := 1;
backup_writefile := 1;
no_confirm := 1;
quiet := 0;
rename_log := 0;
truncate_log := 0;
rename_local_log := 0;
hotlog_filename := 'c:/app/appdb.log';
//backup_interrupted := '1';
end;
最起碼這裡字符的賦值是錯了的!應該用函數strcopy,例如:strcopy(output_dir,'c:/app/backup');
 
N

netCobra

Unregistered / Unconfirmed
GUEST, unregistred user!
为什么?是我把const char _fd_转换为PChar不对呢,还是我对PChar赋值的方法错误?
 
L

leizengzheng

Unregistered / Unconfirmed
GUEST, unregistred user!
遇到过,结构类型不匹配。具体在那里,自己查吧
 
N

netCobra

Unregistered / Unconfirmed
GUEST, unregistred user!
To leizengzheng:能不能帮我看看是哪里改错了?谢谢!!!
 

深之蓝

Unregistered / Unconfirmed
GUEST, unregistred user!
C/C++的DLL与Delphi的动态库入口定位略有区别,如果你需要解决此类问题,可以先将DLL和需要调用函数名Email给我:toyzn@yahoo.com.cn
 
顶部