2

我在翻译 c++ 头文件时遇到了麻烦。当我执行我的 Delphi 代码时,它返回代表“无效参数”的代码 125。我将解释到目前为止我所做的事情:

头文件(片段):

IDSEXP is_AOI(HIDS hCam, UINT nCommand, void *pParam, UINT SizeOfParam);

我的翻译:

function is_AOI(hCam: Cardinal; Command: Cardinal; Param: Pointer; ParamSize: Cardinal): integer; cdecl; external 'ueye_api.dll';

示例 C++ 代码:

IS_SIZE_2D imageSize;
imageSize.s32Width = m_nSizeX;
imageSize.s32Height = m_nSizeY;
is_AOI(m_hCam, IS_AOI_IMAGE_SET_SIZE, (void*)&imageSize, sizeof(imageSize));

我的代码:

var
  size2D: TSize2D;

size2D.S32X := maxWidth;
size2D.S32Y := maxHeight;
ret := is_AOI(cam, IS_AOI_IMAGE_SET_SIZE, Pointer(@size2D), SizeOf(size2D));

C++结构:

typedef struct 
{
    INT s32Width;
    INT s32Height;
} IS_SIZE_2D;

还有我的翻译:

TSize2D = record
  S32X, S32Y: integer;
end;
4

2 回答 2

4

虽然 to 的翻译是正确的,但我通常发现用无类型参数 pointer替换 a 更优雅。*voidvar

hCam是一个Handle,实际上是一个指针;您应该为此使用NativeUintor UIntPtr,否则代码将中断 64 位。请注意,这THandle仅适用于 Windows API 调用,这是一个 Google dll。

Delphi 7 警告
Delphi 7 似乎认为SizeOf(NativeUInt) = 8这已在 D2009 中修复,您可以通过

{$IFNDEF VER200}  //anything prior to Delphi 2009
type
  NativeUInt = Cardinal;
  NativeInt = Integer;
{$ENDIF}

IDSEXP定义如下:
注意调用约定只有cdecl32 位。在 64 位中,使用默认的 Win64 调用约定。

#if defined __i386__
        #define IDSEXP    __attribute__((cdecl)) INT
        #define IDSEXPUL  __attribute__((cdecl)) ULONG
#else
        #define IDSEXP    INT
        #define IDSEXPUL  ULONG
#endif

然而,根据@David 的评论,x64 忽略调用约定关键字,因为只有一个,所以定义应该如下所示:

function is_AOI(hCam: NativeUInt; 
                Command: Cardinal; 
                var Param; 
                ParamSize: Cardinal): integer; 
                cdecl; external 'ueye_api.dll';

您现在可以这样称呼它:

ret:= is_AOI(cam, IS_AOI_IMAGE_SET_SIZE, size2D, SizeOf(size2D));

真正导致函数失败的
原因 起初我认为错误 125 是运行时错误,但它实际上是函数的返回值。
可以调用函数并返回值的事实意味着您的函数的签名很好。
您提供的句柄无效,或者您的 Size2D 参数超出范围。因为你正在通过maxint,我认为你在这里推你的运气。

传递一些更合理的东西Size2D

size2D.S32X := 100;
size2D.S32Y := 100;
ret := is_AOI(cam, IS_AOI_IMAGE_SET_SIZE, size2D, SizeOf(size2D));
于 2013-10-09T19:16:10.730 回答
1

您现有的代码是对本机代码的完美翻译。在 C++ 中,void*是一个无类型指针。Delphi 中的等价类型是Pointer. 换句话说,您已经正确翻译了该参数。

我唯一能发现不正确的是它HIDS可能是一个指针大小的整数。UIntPtr因此,如果您使用的是支持该类型的现代 Delphi,它可能应该被声明为。但是,我希望您的代码是 32 位的,所以这对您来说可能不是问题。

所以结论是你的标题翻译是足够的,你确实传递了无效的参数。您的问题的解决方案将要求您研究库的文档并确保您以正确的顺序调用所有必需的函数,并使用正确的参数。

于 2013-10-09T22:28:03.217 回答