在Delphi中如何调用VC写的DLL呢?(100分)

  • 主题发起人 主题发起人 zhiqunluo
  • 开始时间 开始时间
Z

zhiqunluo

Unregistered / Unconfirmed
GUEST, unregistred user!
在Delphi中如何调用VC写的DLL呢?我在VC中调用正常,但用Delphi调用出错。
不知什么原因,望各位指点指点。先谢了!
 
最主要的是如何在Delphi中聲明該過程(函數)的格式,參數.
你給出該函數在C中的聲明,參數格式,相信會有人幫你解決的.
 
首先VC创建的DLL最好不要是MFC的!因为这样的话VC会把其中函数名变得很怪异!
导致DELPHI无法通过函数名访问函数.
使用的函数名最好通过
extern c 申明!
其次,stdcall和cdecl是不同的,最好看一下帮助
区别是谁来释放参数栈空间,stdcall是调用者,cdecl是被调用者
很久不用了,都快忘干净了!
 
给出VC中的函数声明先。
 
我在VC中是这样申明的:
extern "C" BOOL InitPort( UINT portnr = 1,
UINT baud = 19200,
char parity = 'N',
UINT databits = 8,
UINT stopsbits = 1,
DWORD dwCommEvents = EV_RXCHAR|EV_CTS,
UINT nBufferSize = 4096);
在Delphi中是这样引用的:
function InitPort(portnr:Word;baud:word;parity:char;databit:word,dwCommEvents:DWord,nBufferSize:word):Boolean; external 'vcdll.dll';

但调用时会出错???
 
改成这样:
VC中:
extern "C" BOOL _declspec(dllexport) InitPort(...);
~~~~~~~~~~~~~~~~~~~~~~
Delphi中:
function InitPort(...):Boolean; cdecl; external 'vcdll.dll';
~~~~~~~
 
谢谢各位的帮位,我在DLL中使用的是MFC类。调用的时候没有什么反应,什么原因呢?
程序如下:
BOOL InitPort(
//CWnd* pPortOwner,
UINT portnr,
UINT baud,
char parity,
UINT databits,
UINT stopsbits,
DWORD dwCommEvents,
UINT nBufferSize)
{

//assert(portnr > 0 && portnr < 5);
//assert(pPortOwner != NULL);

//if the thread is alive : Kill

if (m_bThreadAlive)
{
do
{
SetEvent(m_hShutdownEvent);
} while (m_bThreadAlive);
//TRACE("Thread ended/n");
}



//create events
if (m_ov.hEvent != NULL)
ResetEvent(m_ov.hEvent);
m_ov.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

// initialize overlapped structure members to zero
m_ov.OffsetHigh = 0;
m_ov.Offset = 0;

if (m_hWriteEvent != NULL)
ResetEvent(m_hWriteEvent);
m_hWriteEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

if (m_hShutdownEvent != NULL)
ResetEvent(m_hShutdownEvent);
m_hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

// initialize the event objects
m_hEventArray[0] = m_hShutdownEvent;
m_hEventArray[1] = m_ov.hEvent;
m_hEventArray[2] = m_hWriteEvent;

// initialize critical section
InitializeCriticalSection(&m_csCommunicationSync);

if (m_szWriteBuffer != NULL)
delete [] m_szWriteBuffer;
m_szWriteBuffer = new char[nBufferSize];

// set buffersize for writing and save the owner
//m_pOwner = pPortOwner;

m_nPortNr = portnr;
m_dwCommEvents = dwCommEvents;

BOOL bResult = FALSE;
char *szPort = new char[50];
char *szBaud = new char[50];

//now it critical!
EnterCriticalSection(&m_csCommunicationSync);

if (m_hComm != NULL)
{
CloseHandle(m_hComm);
m_hComm = NULL;
}

// prepare port strings
sprintf(szPort,"COM%d",portnr);
sprintf(szBaud,"baud=%d parity=%c data=%d stop=%d",baud,parity,databits,stopsbits);
// get a handle to the port
m_hComm = CreateFile(szPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);

if (m_hComm == INVALID_HANDLE_VALUE)
{
//port not found
delete [] szPort;
delete [] szBaud;

return FALSE;
}
//set the timeout values
/*:超时控制的设置。超时有两种:
区间超时:(仅对从端口中读取数据有用)它指定在读取两个字符之间要经历的时间;
总超时: 当读或写特定的字节数需要的总时间超过某一阈值时,超时触发。计算超时可以根据公式:
ReadTotalTimeout = (ReadTotalTimeoutMultiplier * bytes_to_read)+
ReadToTaltimeoutConstant
WriteTotalTimeout = (WriteTotalTimeoutMuliplier * bytes_to_write)+
WritetoTotalTimeoutConstant
如果在设置超时时参数为0则为无限等待,即无超时。

*/
//设置超时
m_CommTimeouts.ReadIntervalTimeout = 1000;
m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;

if (!SetCommTimeouts(m_hComm,&m_CommTimeouts))
{
CloseHandle(m_hComm);
return FALSE;
}

//设置发送、接收缓存大小
if (!SetupComm(m_hComm,nBufferSize,nBufferSize))
{
CloseHandle(m_hComm);
return FALSE;
}
//设置事件
if (!SetCommMask(m_hComm, dwCommEvents))
{
CloseHandle(m_hComm);
return FALSE;
}
//设置dcb
if (!GetCommState(m_hComm, &m_dcb))
{
CloseHandle(m_hComm);
return FALSE;
}
//硬件流控制
//dcb.fDtrControl = DTR_CONTROL_DISABLE ;
//软件流控制
m_dcb.fRtsControl = RTS_CONTROL_ENABLE;

if (!BuildCommDCB(szBaud, &m_dcb))
{
CloseHandle(m_hComm);
return FALSE;
}

if (!SetCommState(m_hComm, &m_dcb))
{
CloseHandle(m_hComm);
return FALSE;
}

delete [] szPort;
delete [] szBaud;

// flush the port
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

////////////连接数据库//////////////
HRESULT hr;
try
{
hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
if(SUCCEEDED(hr))
{
hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=MonitorCom.mdb","","",adModeUnknown);///连接数据库
///上面一句中连接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97,需要改为:Provider=Microsoft.Jet.OLEDB.3.51; }
}
}
catch(_com_error e)///捕捉异常
{
CString errormessage;
errormessage.Format("连接数据库失败!/r/n错误信息:%s",e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
return FALSE;
}

m_pConnection->Execute("Delete * from ReturnMsg",NULL,adCmdText);
m_ReturnID = 0;

//m_pRecordset->Close;
//m_pRecordset.CreateInstance("ADODB.Recordset");

//AfxMessageBox("初始化成功");

AT_Convert("ATE0");
Sleep(2000);
AT_Convert("AT+CMGF=0");
Sleep(2000);
AT_Convert("AT+CSCA?",30);
Sleep(1500);

// release critical section
LeaveCriticalSection(&m_csCommunicationSync);


return TRUE;
}
 
接受答案了.
 
后退
顶部