从 Delphi 中的 vidcap.h 调用 IKsTopologyInfo::CreateNodeInstance
我正在用 Delphi 编写一个管理网络摄像头的小应用程序。我有 C++ 中的工作示例代码,我需要在 Delphi 中重写它作为我的应用程序的一部分。在 Delphi 中,一切工作正常,除了单个方法调用,它崩溃并显示“模块‘vidcap.ax’中地址 63252469 处的访问冲突。写入地址 11D206FD”消息。
这是可以工作的 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++ 中则工作正常。< br> 逐步调试器期间的检查没有显示任何差异 - 在 Delphi 和 C++ 中,dwNumNodes 都为 11,然后当 i==3 且 guidNodeType=={941C7AC0-C559-11D0-8A2B-00A0C9255AC1} 时 IsEqualGUID 返回 TRUE。因此,在这两种情况下,它都会使用相同的值 i=3 和 IID_IKsControl={28F54685-06FD-11D2-B27A-00A0C9223196}
调用 CreateNodeInstance 遗憾的是,我找不到 vidcap.h 转换为 Delphi .pas 文件,所以我写了我自己对 IKsTopologyInfo 的描述,我想我在 CreateNodeInstance 方法描述中有错误。这是来自 vidcap.h:
virtual HRESULT STDMETHODCALLTYPE CreateNodeInstance(
/* [in] */ DWORD dwNodeId,
/* [in] */ REFIID iid,
/* [out] */ void **ppvObject) = 0;
这是我的 Delphi 变体:
function CreateNodeInstance(dwNodeId:DWord; iid:TGuid; p:Pointer):HRESULT; stdcall;
我使用第三个参数尝试了很多变体 - var Obj、Pointer、PPointer(即 ^Pointer),并且还尝试将不同的变体值传递给它(IKsControl、^IKsControl、^(^IKsControl)、Pointer、^Pointer - 但它们都不起作用。无论如何,我遇到了同样的错误。
需要有关如何使其工作以及如何工作的任何建议应该查看正确的 IKsTopologyInfo.CreateNodeInstance 描述并在 Delphi 中调用。
I'm writing a tiny app managing webcam in Delphi. I have working sample piece of code in C++, and i need to rewrite it in Delphi as a part of my app. All works fine in Delphi, except single method call, which crashes with "Access violation at address 63252469 in module 'vidcap.ax'. Write of address 11D206FD" message.
Here is a part of C++ sample code which works (without errors handling):
#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);
And here is a corresponding part of my code in 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);
The error occurs in the Delphi code at the last line here, while in the C++ it works fine.
Inspection during step-by-step debugger does not show any differences - both in Delphi and C++ it gets 11 for dwNumNodes, then IsEqualGUID returns TRUE when i==3 and guidNodeType=={941C7AC0-C559-11D0-8A2B-00A0C9255AC1}. So in both cases it calls CreateNodeInstance with the same values i=3 and IID_IKsControl={28F54685-06FD-11D2-B27A-00A0C9223196}
To my pity, i couldn't find vidcap.h transformed to Delphi .pas file, so i written my own description for IKsTopologyInfo, and i suppose that i have error in CreateNodeInstance method description. Here it is from vidcap.h:
virtual HRESULT STDMETHODCALLTYPE CreateNodeInstance(
/* [in] */ DWORD dwNodeId,
/* [in] */ REFIID iid,
/* [out] */ void **ppvObject) = 0;
And here is my variant for Delphi:
function CreateNodeInstance(dwNodeId:DWord; iid:TGuid; p:Pointer):HRESULT; stdcall;
I tried a lot of variants with the third parameter - var Obj, Pointer, PPointer (which is ^Pointer), and also tried to pass different variants values to it (IKsControl, ^IKsControl, ^(^IKsControl), Pointer, ^Pointer - and none of them work. In any case i got the same error.
Need any advice on how make it working, and how should look correct IKsTopologyInfo.CreateNodeInstance description and call in Delphi.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据 MSDN REFIID 的定义:
所以
REFIID
是一个指向GUID
的指针,应该翻译为PGUID
或者,iid
是一个输入参数,似乎是强制的,也可以作为const
TGUID
传递。另外,MSDN 指出 CreateNodeInstance :
所以第三个参数应该声明为一个接口的指针,以便允许Delphi管理它。将其声明为
var
IUnknown
或者,因为它是输出参数,所以声明为out
IUnknown
强制该参数是IUnknown
类型的变量,因此必须将其转换为真实的接口类型才能使用它。C++ 声明
变为
And 可以按如下方式调用:
According to MSDN definition of REFIID:
So
REFIID
is a pointer to aGUID
and should be translated asPGUID
or, asiid
is an input parameter and seems to be mandatory, can also be passed as aconst
TGUID
.Also, MSDN states that in CreateNodeInstance:
So the third parameter should be declared as a pointer to an interface in order to allow Delphi to manage it. Declaring it as a
var
IUnknown
or, as it is an output parameter, as anout
IUnknown
forces the parameter to be a variable of typeIUnknown
and therefore that must be casted to the real interface type for using it.The C++ declaration
becomes
And can be called as follows: