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

への変換は正しいですが、通常は a を型指定されていないパラメーターpointerに置き換える方がエレガントだと思います。 *voidvar

hCam実際にはポインターであるハンドルです。NativeUintそのためにorを使用する必要があります。そう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 は1 つしかないため、呼び出し規約のキーワードを無視するため、定義は次のようになります。

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 に答える