我在从delphi调用c dll中的函数时遇到问题.
c函数定义如下
BALL_SCRUB_DLL_API int CALLING_CONVENTION bsl2_ModelBallFlight(float cam_X,
float cam_Y,
float cam_Z,
Ball3d* ball_data_in,
int n_balls_in,
Ball3d* ball_data_out,
int &n_balls_out);
球结构如下所示:
typedef struct
{ float X;
float Y;
float Z;
float VX;
float VY;
float VZ;
int frame_id;
int flag;
} Ball3d;
我想从我的delphi应用程序发送一个ball_data_in数组,c dll将返回相同的数组类型,但在ball_data_out中有修改后的值.
我已经定义了TBall3D记录如下:
TBall3D = record
X : Single;
Y : Single;
Z : Single;
VX : Single;
VY : Single;
VZ : Single;
Framecount : Integer;
BallFlag : Integer;
end;
PBall3D = ^TBall3D;
TBall3DArray = array of TBall3D;
PBall3DArray = ^TBall3DArray;
我的函数declration如下所示:
TBSL2_ModelBallFlight = function( const Cam_X, Cam_Y, Cam_Z : Single;
const ball_data_in : PBall3DArray;
const NFramesIn : Integer;
var ball_data_out : PBall3DArray;
const NFramesOut : Integer) : Integer; cdecl;
我如何从delphi调用dll?任何帮助将受到高度赞赏.
最佳答案 问题出在这里:
TBall3DArray = array of TBall3D;
那是一个动态数组.这是一种不适合互操作的Delphi数据类型.您可以使用动态数组来保存数据,但不能作为跨互操作边界的参数.在任何情况下,动态数组变量都是指向第一个元素的指针.但是你传递的指针的地址是间接的一个层次太多了.
像这样声明导入:
TBSL2_ModelBallFlight = function(
Cam_X: Single;
Cam_Y: Single;
Cam_Z: Single;
ball_data_in: PBall3D;
NFramesIn: Integer;
ball_data_out: PBall3D;
var NFramesOut: Integer
): Integer; cdecl;
这是C代码的直接翻译.如果C代码使用Ball3d *(指向Ball3d的指针),则使用PBall3D,一个指向TBall3D的指针.
还要注意最终参数的细微差别.在C代码中,它是int& n_balls_out.这是对int的引用.所以在Delphi中将它设为var参数.
为了调用代码,您可以使用动态数组类型.声明输入和输出数据的变量:
var
ball_data_in, ball_data_out: TBall3DArray;
您需要通过调用SetLength来初始化数组.然后当你传递参数时,使用@ball_data_in [0]或PBall3D(ball_data_in).同样对于out参数.
我不知道该函数的精确协议,因为原型很少,但调用可能如下所示:
SetLength(ball_data_in, NFramesIn);
SetLength(ball_data_out, NFramesOut);
retval := bsl2_ModelBallFlight(..., PBall3D(ball_data_in), NFramesIn,
PBall3D(ball_data_out), NFramesOut);