我在翻译 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;
最佳答案
虽然对 pointer
的翻译是正确的,但我通常发现用无类型的 var
参数替换 *void
更优雅。
hCam
是一个Handle,它实际上是一个指针;您应该使用 NativeUint
或 UIntPtr
来实现此目的,否则代码将在 64 位中中断。请注意,THandle
仅适用于 Windows API 调用,并且这是一个 Google dll。
Delphi 7 警告
Delphi 7 seems to think that SizeOf(NativeUInt) = 8
,这已在 D2009 中修复,您可以通过
{$IFNDEF VER200} //anything prior to Delphi 2009
type
NativeUInt = Cardinal;
NativeInt = Integer;
{$ENDIF}
IDSEXP
定义如下:
请注意,32 位中的调用约定仅为cdecl
。在 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));
关于C++ 到 Delphi 头文件翻译 : function with pointer to void,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19280570/