2011-09-11 183 views
4

我正在寫Delphi管理網絡攝像頭的一個小應用程序。我在C++中編寫了一段代碼示例,我需要在Delphi中將它重寫爲我的應用程序的一部分。 Delphi中的所有工作都很好,除了單個方法調用,它會在「vidcap.ax」模塊中的地址63252469處出現訪問衝突。寫入地址11D206FD「消息。從德爾福vidcap.h調用IKsTopologyInfo :: CreateNodeInstance

這裏是C++代碼示例其中一部分工作(沒有錯誤處理):

#include <vidcap.h>   // For IKsTopologyInfo 
#include <ksproxy.h>  // For IKsControl 
.... 
//pKsTopologyInfo is passed from the outside 
IKsControl *pKsControl = NULL; 
DWORD dwNumNodes = 0; 
pKsTopologyInfo->get_NumNodes(&dwNumNodes); 
for(unsigned int i = 0; i < dwNumNodes; i++) 
{ 
    pKsTopologyInfo->get_NodeType(i, &guidNodeType); 
    if(IsEqualGUID(guidNodeType, KSNODETYPE_DEV_SPECIFIC)) 
    { 
    hr = pKsTopologyInfo->CreateNodeInstance(i, IID_IKsControl, (void **)&pKsControl); 

這裏是我的代碼在Delphi中的相應部分:

//KsTopologyInfo is IKsTopologyInfo passed from the outside 
//pKsControl is ^IKsControl, which is taken from DirectShow9.pas from DSPack components set. 
KsTopologyInfo.get_NumNodes(@dwNumNodes); 
for i:=0 to dwNumNodes-1 do 
begin 
    KsTopologyInfo.get_NodeType(i,@guidNodeType); 
    if IsEqualGUID(guidNodeType,KSNODETYPE_DEV_SPECIFIC) then 
    begin 
    KsTopologyInfo.CreateNodeInstance(i,IID_IKsControl,@pKsControl); 

發生錯誤Delphi代碼在這裏的最後一行,而在C++中它工作正常。
循序漸進調試程序中的檢查沒有顯示任何差異 - 在Delphi和C++中它都爲dwNumNodes取11,然後當i == 3和guidNodeType == {941C7AC0-C559-11D0-8A2B-00A0C9255AC1時IsEqualGUID返回TRUE }。因此,在這兩種情況下調用CreateNodeInstance其中i = 3和IID_IKsControl = {28F54685-06FD-11D2-B27A-00A0C9223196}

讓我遺憾,我找不到vidcap.h轉化爲德爾福的.pas文件相同的值,所以我爲IKsTopologyInfo寫了自己的描述,並且我想我在CreateNodeInstance方法描述中有錯誤。這是從vidcap.h:

virtual HRESULT STDMETHODCALLTYPE CreateNodeInstance( 
    /* [in] */ DWORD dwNodeId, 
    /* [in] */ REFIID iid, 
    /* [out] */ void **ppvObject) = 0; 

這裏是我的德爾福變種:

function CreateNodeInstance(dwNodeId:DWord; iid:TGuid; p:Pointer):HRESULT; stdcall; 

我嘗試了很多與第三參數變種 - 無功的OBJ,指針,PPointer(這是^指針),並試圖傳遞不同的變體值(IKsControl,^ IKsControl,^(^ IKsControl),指針,^指針 - 並且它們都不起作用。需要關於如何使它工作的任何建議,以及如何正確顯示IKsTopologyInfo.CreateNodeInstance描述離子和德爾福呼叫。

回答

2

根據MSDN definition of REFIID

typedef GUID IID; 
typedef IID* REFIID; 

所以REFIID是一個指向GUID,應譯爲PGUID或作爲iid是輸入參數,似乎是強制性的,也可以作爲一個傳遞constTGUID

此外,MSDN指出,在CreateNodeInstance

ppvObject接收指向節點對象上所請求的接口。 來電者必須釋放接口

所以第三個參數應該被聲明爲一個接口的指針,以便Delphi能夠管理它。聲明它爲varIUnknown,或者因爲它是輸出參數,所以作爲outIUnknown強制該參數爲IUnknown類型的變量,因此必須將其轉換爲真實接口類型才能使用它。

的C++聲明

virtual HRESULT STDMETHODCALLTYPE CreateNodeInstance( 
    /* [in] */ DWORD dwNodeId, 
    /* [in] */ REFIID iid, 
    /* [out] */ void **ppvObject) = 0; 

成爲

function CreateNodeInstance(dwNodeId: DWord; const iid: TGUID; ppvObject: PUnknown): HRESULT; stdcall; 

而且可以如下叫:

var 
    KsControl: IKsControl; 

KsTopologyInfo.CreateNodeInstance(i, IID_IKsControl, @KsControl); 
+0

的偉大工程!謝謝。似乎真正的問題是,我沒有注意到iid是REFIID,並試圖通過TGUID,而不是const也。 – alex