关于 DLL 的调用问题,好象难倒了一大堆... (200分)

  • 主题发起人 主题发起人 ddev
  • 开始时间 开始时间
D

ddev

Unregistered / Unconfirmed
GUEST, unregistred user!
问题:关于 DLL 的调用问题<br><br>我在 VC5 中做了一个关于 ACCESS 的处理函数。但在 Delphi 中调用时,却总出现外部调用异常。<br>能指导一下吗?<br><br>daoCreateDatabase()调用正常;<br>但daoCreateTable()就出错,问题可能出现在 DAOFIELDDEF** 的调用参数上。对于这种指向数组的<br>指针,不知在 Delphi 中应该处理?<br><br>源代码如下:<br><br>//****************************************************************************************//<br>VC5 DLL<br>//****************************************************************************************//<br>#include &lt;afxdao.h&gt;<br><br>typedef struct tagDaoFieldDef{<br><br> char fldName[40];<br> int fldType;<br> int fldSize;<br> bool fldRequired;<br> bool fldAllowZeroLength;<br><br>}DAOFIELDDEF;<br><br>extern "C"{<br><br> __declspec(dllexport) bool __stdcall daoCreateDatabase(LPCTSTR);<br> __declspec(dllexport) bool __stdcall daoCreateTable(LPCTSTR, LPCTSTR, DAOFIELDDEF**, int);<br>};<br><br>//-----------------------------------------------------------------------------------------//<br>#include "DaoAPI.h"<br><br>extern "C"{<br><br> __declspec(dllexport) bool __stdcall daoCreateDatabase(LPCTSTR lpszDatabaseName)<br> {<br> bool bSuccess = FALSE;<br> CDaoDatabase* lpDatabase = new CDaoDatabase();<br> try{<br><br> lpDatabase-&gt;Create(lpszDatabaseName);<br> if (lpDatabase-&gt;IsOpen()) lpDatabase-&gt;Close();<br> bSuccess = TRUE;<br> }<br> catch(CDaoException&amp; E){<br> bSuccess = FALSE;<br> E.Delete();<br> }<br> catch(CMemoryException &amp; E){<br> bSuccess = FALSE;<br> E.Delete();<br> } <br> delete lpDatabase;<br> lpDatabase = NULL;<br><br> return bSuccess;<br> }<br><br> __declspec(dllexport) bool __stdcall daoCreateTable(LPCTSTR lpszDatabaseName, <br> LPCTSTR lpszTableName, DAOFIELDDEF** lpFieldDefs, int nCount)<br> {<br> bool bSuccess = FALSE;<br> CDaoDatabase* lpDatabase = new CDaoDatabase();<br> try{<br><br> lpDatabase-&gt;Open(lpszDatabaseName);<br><br> CDaoTableDef* lpTableDef = new CDaoTableDef(lpDatabase);<br> CDaoFieldInfo FieldInfo;<br> try{<br> lpTableDef-&gt;Create(lpszTableName);<br> for(int i = 0; i &lt; nCount; i++)<br> {<br> DAOFIELDDEF* lpFieldDef = (DAOFIELDDEF*)(lpFieldDefs);<br> if (lpFieldDef != NULL)<br> {<br> FieldInfo.m_strName = lpFieldDef-&gt;fldName;<br> FieldInfo.m_nType = lpFieldDef-&gt;fldType;<br> FieldInfo.m_lSize = lpFieldDef-&gt;fldSize;<br> FieldInfo.m_bRequired = lpFieldDef-&gt;fldRequired;<br> FieldInfo.m_bAllowZeroLength = lpFieldDef-&gt;fldAllowZeroLength;<br> <br> lpTableDef-&gt;CreateField(FieldInfo);<br> }<br> }<br><br> lpTableDef-&gt;Append();<br> bSuccess = TRUE;<br> }<br> catch(CDaoException&amp; E){<br> bSuccess = FALSE;<br> E.Delete();<br> }<br> catch(CMemoryException &amp; E){<br> bSuccess = FALSE;<br> E.Delete();<br> } <br> lpTableDef-&gt;Close();<br><br> delete lpTableDef;<br> lpTableDef = NULL;<br> }<br> catch(CDaoException&amp; E){<br> bSuccess = FALSE;<br> E.Delete();<br> }<br> catch(CMemoryException &amp; E){<br> bSuccess = FALSE;<br> E.Delete();<br> } <br> delete lpDatabase;<br> lpDatabase = NULL;<br><br> return bSuccess;<br> }<br>}<br>//-----------------------------------------------------------------------------------------//<br><br>//****************************************************************************************//<br>Delphi Call<br>//****************************************************************************************//<br>unit DaoAPI;<br><br>interface<br><br>uses<br>&nbsp; windows;<br><br>const<br>&nbsp; &nbsp; dbBoolean &nbsp; &nbsp; &nbsp; &nbsp; = 1;<br>&nbsp; &nbsp; dbByte &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br>&nbsp; &nbsp; dbInteger &nbsp; &nbsp; &nbsp; &nbsp; = 3;<br>&nbsp; &nbsp; dbLong &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br>&nbsp; &nbsp; dbCurrency &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br>&nbsp; &nbsp; dbSingle &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 6;<br>&nbsp; &nbsp; dbDouble &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 7;<br>&nbsp; &nbsp; dbDate &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 8;<br>&nbsp; &nbsp; dbBinary &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 9;<br>&nbsp; &nbsp; dbText &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 10;<br>&nbsp; &nbsp; dbLongBinary &nbsp; &nbsp; &nbsp;= 11;<br>&nbsp; &nbsp; dbMemo &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 12;<br>&nbsp; &nbsp; dbGUID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 15;<br>&nbsp; &nbsp; dbBigInt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 16;<br>&nbsp; &nbsp; dbVarBinary &nbsp; &nbsp; &nbsp; = 17;<br>&nbsp; &nbsp; dbChar &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 18;<br>&nbsp; &nbsp; dbNumeric &nbsp; &nbsp; &nbsp; &nbsp; = 19;<br>&nbsp; &nbsp; dbDecimal &nbsp; &nbsp; &nbsp; &nbsp; = 20;<br>&nbsp; &nbsp; dbFloat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 21;<br>&nbsp; &nbsp; dbTime &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 22;<br>&nbsp; &nbsp; dbTimeStamp &nbsp; &nbsp; &nbsp; = 23;<br><br>type<br>&nbsp; PDaoFieldDef = ^TDaoFieldDef;<br>&nbsp; TDaoFieldDef = record<br> &nbsp;fldName: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;string[40];<br> &nbsp;fldType: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Longint;<br> &nbsp;fldSize: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Longint;<br> &nbsp;fldRequired: &nbsp; &nbsp; &nbsp; &nbsp;Boolean;<br> &nbsp;fldAllowZeroLength: Boolean;<br>&nbsp; end;<br><br>&nbsp; PDaoFieldDefArr = ^TDaoFieldDefArr;<br>&nbsp; TDaoFieldDefArr = array of PDaoFieldDef;<br><br>function daoCreateDatabase(lpszDatabaseName: LPCTSTR): Boolean; stdcall;<br>function daoCreateTable(lpszDatabaseName: LPCTSTR; lpszTableName: LPCTSTR;<br>&nbsp; lpFieldDefList: PDaoFieldDefArr; nCount: Longint): Boolean; stdcall;<br><br>implementation<br>&nbsp; &nbsp; &nbsp; &nbsp;<br>function daoCreateDatabase; stdcall; external 'DaoAPI.dll';<br>function daoCreateTable; stdcall; external 'DaoAPI.dll';<br><br>end.<br><br>//-----------------------------------------------------------------------------------------//<br>unit DemoFrm;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; TDemoForm = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; Edit2: TEdit;<br>&nbsp; &nbsp; ResultEdit: TEdit;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; DemoForm: TDemoForm;<br><br>implementation<br><br>uses DaoAPI, db;<br><br>{$R *.DFM}<br><br>procedure TDemoForm.Button1Click(Sender: TObject);<br>var<br>&nbsp; bSuccess: Boolean;<br>begin<br>&nbsp; bSuccess := daoCreateDatabase(PChar(Edit1.Text));<br>&nbsp; if bSuccess then<br>&nbsp; &nbsp; ResultEdit.Text := 'Success' else<br>&nbsp; &nbsp; ResultEdit.Text := 'Fail!';<br>end;<br><br>procedure TDemoForm.Button2Click(Sender: TObject);<br>var<br>&nbsp; bSuccess: Boolean;<br>&nbsp; FieldDefs: PDaoFieldDefArr;<br>begin<br>&nbsp; FieldDefs := New(PDaoFieldDefArr);<br>&nbsp; SetLength(FieldDefs^, 4);<br><br>&nbsp; &nbsp; FieldDefs^[0] := New(PDaoFieldDef);<br>&nbsp; &nbsp; FieldDefs^[0].fldName := '编号';<br>&nbsp; &nbsp; FieldDefs^[0].fldType := dbText;<br>&nbsp; &nbsp; FieldDefs^[0].fldSize := 16;<br>&nbsp; &nbsp; FieldDefs^[0].fldRequired := False;<br>&nbsp; &nbsp; FieldDefs^[0].fldAllowZeroLength := True;<br><br>&nbsp; &nbsp; FieldDefs^[1] := New(PDaoFieldDef);<br>&nbsp; &nbsp; FieldDefs^[1].fldName := '名称';<br>&nbsp; &nbsp; FieldDefs^[1].fldType := dbText;<br>&nbsp; &nbsp; FieldDefs^[1].fldSize := 80;<br>&nbsp; &nbsp; FieldDefs^[1].fldRequired := False;<br>&nbsp; &nbsp; FieldDefs^[1].fldAllowZeroLength := True;<br><br>&nbsp; &nbsp; FieldDefs^[2] := New(PDaoFieldDef);<br>&nbsp; &nbsp; FieldDefs^[2].fldName := '年龄';<br>&nbsp; &nbsp; FieldDefs^[2].fldType := dbLong;<br>&nbsp; &nbsp; FieldDefs^[2].fldSize := 0;<br>&nbsp; &nbsp; FieldDefs^[2].fldRequired := False;<br>&nbsp; &nbsp; FieldDefs^[2].fldAllowZeroLength := False;<br><br>&nbsp; &nbsp; FieldDefs^[3] := New(PDaoFieldDef);<br>&nbsp; &nbsp; FieldDefs^[3].fldName := '备注';<br>&nbsp; &nbsp; FieldDefs^[3].fldType := dbMemo;<br>&nbsp; &nbsp; FieldDefs^[3].fldSize := 10;<br>&nbsp; &nbsp; FieldDefs^[3].fldRequired := False;<br>&nbsp; &nbsp; FieldDefs^[3].fldAllowZeroLength := True;<br><br>&nbsp; bSuccess := daoCreateTable(PChar(Edit1.Text), PChar(Edit2.Text), FieldDefs, 4);<br>&nbsp; if bSuccess then<br>&nbsp; &nbsp; ResultEdit.Text := 'Success' else<br>&nbsp; &nbsp; ResultEdit.Text := 'Fail!';<br><br>end;<br><br>end.<br><br>//-----------------------------------------------------------------------------------------//<br>
 
在C/C++中的函数调用约定与Pascal中是不一样的,Pascal是顺序传递参数,而C/C++正好<br>相反,你试试看。
 
这个问题怎么会没人回答???????<br>这么难?
 
我没有仔细看你的代码,能不能试试把<br><br>&nbsp; PDaoFieldDefArr = ^TDaoFieldDefArr;<br>&nbsp; TDaoFieldDefArr = array of PDaoFieldDef;<br><br>改成<br><br>&nbsp; PDaoFieldDefArr = ^TDaoFieldDefArr;<br>&nbsp; TDaoFieldDefArr = ^PDaoFieldDefArr; <br><br>C和delphi对array的处理应该不能通用的。<br>如果还是不能解决,建议你参考一下一个开源的控制KADao<br>是一个对DAO封装得很好的控件,完全Pascal源码<br>你的问题应该能够找到答案<br>到google上搜一下,实在找不到,我寄给你
 
出个什么错,讲一下。
 
to 左轻侯:<br><br>谢谢你的答复,可以把 KaDao 的源码发给我吗?ddev@china.com。谢谢
 
我已经上传<br>http://delphi.itschem.com/dispdoc.asp?id=158
 
多人接受答案了。
 
后退
顶部