function Read(maxsize: SYSINT; var data: PSafeArray): SYSINT;我是这样用的
var
tSA: TSafeArray;
pSA: PSafeArray;
begin
pSA := @tSA;
IXXX.Read(sizeof(TSafeArray),pSA);//运行时总是说参数错误!
end;
var
tSA: TSafeArray;
pSA: PSafeArray;
begin
pSA := @tSA;
IXXX.Read(sizeof(TSafeArray),pSA);//运行时总是说参数错误!
end;
pSA^ := tSA;
IXXX.Read(sizeof(pSA^),pSA);
end; 试试看
是个什么东西和integer不兼容
PSafeArrayBound = ^TSafeArrayBound;
{$EXTERNALSYM tagSAFEARRAYBOUND}
tagSAFEARRAYBOUND = record
cElements: Longint;
lLbound: Longint;
end;
TSafeArrayBound = tagSAFEARRAYBOUND;
{$EXTERNALSYM SAFEARRAYBOUND}
SAFEARRAYBOUND = TSafeArrayBound; PSafeArray = ^TSafeArray;
{$EXTERNALSYM tagSAFEARRAY}
tagSAFEARRAY = record
cDims: Word;
fFeatures: Word;
cbElements: Longint;
cLocks: Longint;
pvData: Pointer;
rgsabound: array[0..0] of TSafeArrayBound;
end;
TSafeArray = tagSAFEARRAY;
{$EXTERNALSYM SAFEARRAY}
SAFEARRAY = TSafeArray;
{ VT_INT and VT_UINT }
{$EXTERNALSYM PSYSINT}
PSYSINT = ^SYSINT;
{$EXTERNALSYM SYSINT}
SYSINT = Integer;
{$EXTERNALSYM PSYSUINT}
PSYSUINT = ^SYSUINT;
{$EXTERNALSYM SYSUINT}
SYSUINT = LongWord;
Access violation at address ............ Write of address 00000025.
tSA: TSafeArray;
pSA: PSafeArray;
begin
getmem(psa,sizeof(tsa));
IXXX.Read(sizeof(TSafeArray),pSA);//运行时总是说参数错误!
//freemem(pas);
end;
调用这个函数我觉得应该是第二个参数问题。
这个原形是谁定义的,好像有问题!!!按照C++的说法Data是一个指针的指针!!!一般我看到的Windows API的定义一般都这么写的:
function Read(maxsize: SYSINT; var data: TSafeArray): SYSINT;
或
function Read(maxsize: SYSINT; data: PSafeArray): SYSINT;
这样有什么意义?
tSA: TSafeArray;
pSA: PSafeArray;
begin
IXXX.Read(sizeof(TSafeArray),pSA);
end;
这样!!
这两种方法是一个意思,都是取的SafeArray的地址但是你这样
function Read(maxsize: SYSINT; var data: PSafeArray): SYSINT;取的就是 PSafeArray的地址,指针的地址有什么意义?
原型为:
function Read(maxsize: SYSINT; var data: PSafeArray): SYSINT; safecall;
// Interface: IWFChannel
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {417DAD92-DCFA-11D2-836D-0008C7826433}
// *********************************************************************//
IWFChannel = interface(IDispatch)
['{417DAD92-DCFA-11D2-836D-0008C7826433}']
function GetInfo(var number: SYSINT; var name: WideString; var file_: WideString): WideString; safecall;
procedure Close; safecall;
procedure Activate; safecall;
procedure Minimize; safecall;
procedure Maximize; safecall;
procedure Restore; safecall;
procedure SetProperty(const property_: WideString; const value: WideString); safecall;
function PortOpen(const config: WideString): WideString; safecall;
procedure PortClose; safecall;
function GetPortStatus: SYSINT; safecall;
function GetBusyStatus: SYSINT; safecall;
procedure SetReadBuffer(size: SYSINT; filter: SYSINT); safecall;
function Read(maxsize: SYSINT; var data: PSafeArray): SYSINT; safecall;
procedure Write(data: PSafeArray); safecall;
function GetPrintoutArray(var flags: SYSINT; var faultcode: SYSINT; var cmd: WideString): PSafeArray; safecall;
function GetPrintoutBuffer(var flags: SYSINT; var faultcode: SYSINT; var cmd: WideString): WideString; safecall;
procedure HideReceivedData(hide: WordBool); safecall;
procedure LockChannel(lock: WordBool); safecall;
procedure TerminalConnect(const username: WideString; const password: WideString); safecall;
procedure TerminalReconnect; safecall;
procedure TerminalRelease; safecall;
procedure TerminalBreak; safecall;
function GetTrafficSettings(var waitconnect: SYSINT): SYSINT; safecall;
procedure SetTrafficSettings(mask: SYSINT; waitconnect: SYSINT; traffic: SYSINT); safecall;
procedure SendCommand(const command: WideString; autoconnect: WordBool); safecall;
procedure Transmit(const file_: WideString; line: SYSINT); safecall;
procedure ScheduleTransmit(const file_: WideString; year: SYSINT; month: SYSINT; day: SYSINT;
hour: SYSINT; min: SYSINT; repeat_: SYSINT; period: SYSINT;
const every: WideString); safecall;
procedure XModemSend(const file_: WideString); safecall;
procedure XModemReceive(const file_: WideString); safecall;
procedure OutputLog(action: SYSINT; const file_: WideString); safecall;
procedure Template(const file_: WideString); safecall;
procedure FindDoc(const book: WideString; const keyword: WideString; faultcode: SYSINT;
const category: WideString); safecall;
procedure Advise(const pIWFEvent: IUnknown; mask: SYSINT); safecall;
procedure Unadvise; safecall;
procedure SetEventMask(mask: SYSINT); safecall;
function GetPrivateData(const guid: WideString; serial: SYSINT; maxsize: SYSINT): PSafeArray; safecall;
procedure SetPrivateData(const guid: WideString; serial: SYSINT; data: PSafeArray); safecall;
end;
我实在是着急啊!请高手帮我看贴:
http://expert.csdn.net/Expert/topic/1885/1885398.xml?temp=.4350397
Example
Include IDL or Type LibraryA COM client does not need to create an IDL file since the interface for an event object is already defined in the WinFIOL IDL or Type Library. To use the WinFIOL IDL file, compile it with MIDL and define: #include <windows.h>
#include <ole2.h>
#include <wfoleaut.h>
#include <wfoleaut_i.c>
#include <atlbase.h>
#include <atlconv.h>
#include <atlconv.cpp>To use the Type Library (Visual C++ only), define: #include <windows.h>
#include <ole2.h>
#import <wfoleaut.tlb>
Design event objectThe event object will have a custom interface, since that is what WinFIOL uses to call the object. The base class IWFEvent is defined in "wfoleaut.h" and "wfoleaut.tlb": class CWFEvent : public IWFEvent
{
int iCount;
IWFChannel * pIWFChannel;
DWORD dwThreadID;
void ReadPrintout(void);
public:
CWFEvent(IWFChannel *chnl);
virtual ~CWFEvent() { }
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
STDMETHOD(Notify)(INT event, BSTR eventstr);
};
ImplementationMost of the code below is standard and can be found in many books about COM. The constructor takes a pointer to IWFChannel to be able to call methods in this interface. CWFEvent::CWFEvent(IWFChannel *chnl)
{
iCount = 0;
pIWFChannel = chnl;
dwThreadID = GetCurrentThreadId();
} STDMETHODIMP CWFEvent::QueryInterface(REFIID riid, void ** ppv)
{
if ( riid == IID_IUnknown )
*ppv = (IUnknown *) this;
else if ( riid == IID_IWFEvent )
*ppv = (IWFEvent *) this;
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
((IUnknown *) *ppv)->AddRef();
return S_OK;
} STDMETHODIMP_(ULONG) CWFEvent::AddRef(void)
{
return ++iCount;
} STDMETHODIMP_(ULONG) CWFEvent::Release(void)
{
if ( iCount == 1 )
{
// make sure message loop is terminated:
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
delete this;
return 0;
}
return --iCount;
} STDMETHODIMP CWFEvent::Notify(INT event, BSTR eventstr)
{
if ( event == WFEVENT_PRINTOUT )
ReadPrintout();
return S_OK;
}
Getting printoutThe function CWFEvent::ReadPrintout( ) is called from CWFEvent::Notify( ) when the WFEVENT_PRINTOUT
is received from WinFIOL. This function calls IWFChannel::GetPrintoutArray( ). You can also call
IWFChannel::GetPrintoutBuffer( ). For simplicity, this example uses the UNICODE version of printf( ) to print a BSTR. If the printout does not originate from the command that the COM client sent, the application needs to wait for the next printout. Otherwise, the WM_QUIT message is sent to the message loop in the send MML command example. void CWFEvent::ReadPrintout(void)
{
BOOL bQuit = TRUE;
SAFEARRAY *sa = NULL;
int flags = 0, faultcode = 0;
BSTR command = NULL; HRESULT hr = pIWFChannel->GetPrintoutArray(&flags, &faultcode, &command, &sa);
if ( SUCCEEDED(hr) )
{
BSTR *bstr;
SafeArrayAccessData(sa, (void **) &bstr);
int nLines = sa->rgsabound->cElements; // number of lines
for ( int i = sa->rgsabound->lLbound; i < nLines; i++ )
wprintf(L"%s", bstr[i]);
SafeArrayUnaccessData(sa);
if ( !command[0] ) // if command is empty, do not quit yet...
bQuit = FALSE;
}
SafeArrayDestroy(sa);
SysFreeString(command);
if ( bQuit )
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
}