aardio 官方社区

 找回密码
 注册会员

QQ登录

只需一步,快速开始

搜索
查看: 9392|回复: 4

api中有个tuple结构体参数,不知道如何定义

[复制链接]

38

主题

129

回帖

1045

积分

荣誉会员

积分
1045
发表于 2018-3-27 00:18:41 | 显示全部楼层 |阅读模式
研究halcon的dll的时候有个tuple参数,一直搞不通,希望谁给指点下:
在halcon的有.h头文件定义这个tuple如下:
  1. typedef   void*   VOIDP;

  2. /*****************************************************************************/
  3. /* Parameter passing (Control parameters)                                    */
  4. /*****************************************************************************/
  5. #define UNDEF_PAR        0       /* Parameter type: no defined type          */
  6. #define LONG_PAR         1       /* Parameter type: long                     */
  7. #define HANDLE_PAR       LONG_PAR /* Parameter type: long                     */
  8. #define FLOAT_PAR        2       /* Parameter type: float                    */
  9. #define STRING_PAR       4       /* Parameter type: string                   */
  10. /* Possible parameter types for a single element: */
  11. #define ANY_ELEM    (LONG_PAR|FLOAT_PAR|STRING_PAR)
  12. #define INT_PAR      LONG_PAR    /* Parameter type: int                      */
  13. #define DOUBLE_PAR  FLOAT_PAR    /* Parameter type: double                   */
  14. #define MIXED_PAR        8       /* Parameter type: Hcpar                    */
  15. #define MAX_TUPLE_TYPE   MIXED_PAR/* maximum type number                     */
  16. /* Possible parameter types for a tuple: */
  17. #define ANY_TUPLE   (LONG_PAR|FLOAT_PAR|STRING_PAR|MIXED_PAR)
  18. /*                      16          reserved */
  19. /*                      32          reserved */
  20. #define POINTER_PAR     64       /* Parameter type: pointer to any type      */
  21. #define TUPLE_PAR      128       /* Parameter type: pointer to tuple         */
  22. #define MAX_PAR     MIXED_PAR


  23. /*****************************************************************************/
  24. /* Constants and basic types                                                 */
  25. /*****************************************************************************/
  26. #define MAX_TUPLE_LENGTH 1000000   /* max. length of a tuple                 */
  27. #define MAX_STRING       1024      /* max. length of a string                */

  28. typedef UINT4            Herror;   /* Type function values (error messages)  */

  29. typedef  long *Hkey;               /* primary key in DB (for iconic objects) */
  30. #define  UNDEF_KEY   (Hkey)(0)     /* Undefined iconic object                */


  31. /*****************************************************************************/
  32. /* Structures for passing parameters between language interface and core     */
  33. /*****************************************************************************/
  34. #ifndef HC_NO_STRUCT_MEMBER_ALIGNMENT
  35. /* sets the struct member alignment to avoid problems if
  36. * the settings of the user differ to those of the HALCON
  37. * version. (8 is the default alignment, generally) */
  38. # pragma pack(push,8)
  39. #endif
  40. typedef union
  41. {
  42.   INT4_8  l;              /* 4/8 byte integer                       (input)  */
  43.   double  d;              /* 8 byte real                            (input)  */
  44.   char    *s;             /* pointer to strings                     (input)  */
  45.   double  f;              /* 8 byte real (legacy 11.0)              (input)  */
  46. } Hpar;                   /* parameter passing for the C interface           */

  47. typedef union
  48. {
  49.   INT4_8  *l;             /* 4/8 byte integer                       (output) */
  50.   double  *d;             /* 8 byte real,                           (output) */
  51.   char    *s;             /* pointer to strings                     (output) */
  52.   VOIDP   p;              /* pointer to var. of any type (e.g. tuple)(output)*/
  53.   double  *f;             /* 8 byte real, (legacy 11.0)             (output) */
  54. } Hvar;                   /* parameter passing for the C interface           */

  55. typedef struct
  56. {
  57.   Hpar   par;             /* values                                          */
  58.   HINT   type;            /* type flag                                       */
  59. } Hcpar;                  /* parameter passing for the C interface           */

  60. typedef struct
  61. {
  62.   Hvar   var;             /* values                                          */
  63.   HINT   type;            /* type flag                                       */
  64. } Hcvar;                  /* parameter passing for the C interface           */

  65. typedef union {
  66.   INT4_8 *l;
  67.   double *d;
  68.   char   **s;
  69.   Hcpar  *cpar;
  70. } Hcelem; /* pure type array */


  71. typedef struct HCTUPLE
  72. {
  73.   Hpar  val;
  74.   HINT  type;
  75.   char  pad[sizeof(Hcpar)-sizeof(Hpar)-sizeof(HINT)]; /* padding for data
  76.                                 * structure alignement to enable val and type
  77.                                 * to get used as Hcpar structure */
  78.   INT4_8 num;                   /* number of set array elements */
  79.   INT4_8 capacity;              /* allocated array length */
  80.   HINT  free;                   /* free array elem when destroying tuple? */
  81.   Hcelem elem;                  /* the actual array */
  82. } Hctuple;
  83. #define HCTUPLE_INITIALIZER {{0},UNDEF_PAR,{0},0,0,0,{NULL}}

  84. typedef struct
  85. {
  86.   Hcvar   *variables;     /* variables (of application) to write back values */
  87.   Hcpar   *element;       /* tuple element(s)                                */
  88.   INT4_8  num_el;         /* number of used elements                         */
  89.   INT4_8  length;         /* total length of array (incl. unused elements)   */
  90. } Hcvtuple;               /* for passing control parameter variables from    */

  91. //这里就是那个tuple的结构体     
  92. typedef struct                /* Tuple representation           */
  93. {
  94.   Hcpar   *tuple;
  95.   INT_PTR length;
  96. } Htuple;
复制代码


于是,我把这个结构体写成class模式来定义:
  1. class Htuple{
  2.     struct tuple ={
  3.         union par ={
  4.                           INT  l ;              /* 4/8 byte integer                       (input)  */
  5.                           double  d;              /* 8 byte real                            (input)  */
  6.                           string s;             /* pointer to strings                     (input)  */
  7.                           float  f;              /* 8 byte real (legacy 11.0)              (input)  */
  8.                         } ;
  9.             INT type;
  10.     };
  11.         addr length;
  12. }

复制代码

调用dll, 声明函数api
然后实例化之后,调用
  1. dll = ..raw.loadDll("\res\halconc.dll","AArHalconC","cdecl");
  2. T_tuple_type= dll.api("T_tuple_type","int(struct T, pointer& Type)");

  3. Htuples = Htuple();

  4. var retapp = raw.realloc(1000);
  5. var ret,TupleType =  T_tuple_type (Htuples, retapp);
  6. console.dump(ret,TupleType)
复制代码


这里运行就会提示:存储保护异常..

还在继续测试其他方法, 有进展此贴会后续更新 , 希望懂静态调用的给提点一下
关于tuple的在线文档: http://www.mvtec.com/doc/halcon/13/en/tuple_type.html

工程下载地址: https://pan.baidu.com/s/19PlTCUTAfCrGUl_1IjNjxA

168

主题

2163

回帖

1万

积分

管理员

积分
13126
发表于 2018-3-27 12:31:53 | 显示全部楼层
C++的类型别名成千上万,但实际上真实的类型就那么几个,
你可以用C++开发环境打开他的C++工程,然后跳转到函数定义、或者类型定义看他使用的真实类型。

你的Htuple声明显然是错的,他的成员是2个指针,指针应当声明为pointer,建议你还是先看一下帮助文档再说。
另外你那个 raw.realloc(1000)也用的莫名其妙,pointer& 指向的是指针的指针,一般这种参数只要传入null,不需要自己分配内存,这些在文档上都有介绍的。

如果你实在搞不清楚,可以换个思路,用C++写个DLL,然后再调用这个DLL你总会吧。
不会翻译这些头文件的话,其实也没有必要去翻译。

38

主题

129

回帖

1045

积分

荣誉会员

积分
1045
 楼主| 发表于 2018-3-29 00:48:04 | 显示全部楼层
谢谢Jacen回复.
搞定了.
原来dll中是有这么个函数可以操作tuple的,包含了创建/设置/销毁.....
简单的tuple操作示例如下:
  1. import console
  2. console.open()

  3. dll = ..raw.loadDll("\res\halconc.dll","AArHalconC","cdecl");
  4. F_create_tuple= dll.api("F_create_tuple","void(pointer& T, int length)");
  5. F_create_tuple_i= dll.api("F_create_tuple_i","void(pointer T, int val)");
  6. F_create_tuple_s=dll.api("F_create_tuple_s","void(pointer T, string val)");
  7. F_get_s=dll.api("F_get_s","string(pointer T, int index)");
  8. F_set_s=dll.api("F_set_s","void(pointer T, string val,int index)");
  9. F_get_i=dll.api("F_get_i","int(pointer T, int index)");
  10. var ctup = raw.buffer(1000);

  11. F_create_tuple(ctup,5);
  12. //console.varDump(ctup)
  13. //F_create_tuple_i(ctup,5);
  14. //F_create_tuple_s(ctup,"abcde");
  15. console.varDump(ctup)
  16. F_set_s(ctup,"abc",0);
  17. F_set_s(ctup,"def",1);
  18. F_set_s(ctup,"ghi",2);
  19. F_set_s(ctup,"jkl",3);
  20. F_set_s(ctup,"mnu",4);
  21. var ret = F_get_s(ctup,2);
  22. console.varDump(ret)
  23. var ret = F_get_s(ctup,1);
  24. console.varDump(ret)
  25. F_set_s(ctup,"hahabb",1);
  26. var ret = F_get_s(ctup,1);
  27. console.varDump(ret)
  28. var ret = F_get_s(ctup,4);
  29. console.varDump(ret)
  30. console.pause(true);
复制代码

终于可以愉快的玩耍了.O(∩_∩)O

38

主题

129

回帖

1045

积分

荣誉会员

积分
1045
 楼主| 发表于 2018-3-29 22:00:30 | 显示全部楼层
昨天说tuple可以利用dll里面的函数进行赋值和操作了.
今天直接拿来放到了上次分享的那个画边界圆的示例里,
发现还是不能正确使用.╮(╯▽╰)╭
这次应该不是tuple参数错误了,估计应该是api调用错误, 试了好几种想法,都不行,吐血..

希望有研究这方面的朋友帮忙给看下, 我也会继续各种测试 , 如果解决了会第一时间更新帖子
  1. import win.ui;
  2. /*DSG{{*/
  3. mainForm = win.form(text="Halcon函数circle测试";right=833;bottom=525)
  4. mainForm.add(
  5. button={cls="button";text="button";left=9;top=9;right=170;bottom=59;z=2};
  6. picturebox={cls="picturebox";left=182;top=0;right=834;bottom=526;bgcolor=8421376;z=1};
  7. snumber={cls="static";text="0";left=18;top=397;right=150;bottom=433;font=LOGFONT(h=-21);transparent=1;z=3}
  8. )
  9. /*}}*/

  10. import console;

  11. var dll = ..raw.loadDll("\res\halconc.dll","halconlib","cdecl");
  12. open_window= dll.api("open_window","int(int Row, int Column, int Width, int Height, int FatherWindow, string Mode, string Machine, int& WindowHandle)");
  13. read_image= dll.api("read_image","int(ADDR& Image, string FileName)");
  14. get_image_size= dll.api("get_image_size","int(ADDR Image, int& Width, int& Height)");
  15. disp_obj= dll.api("disp_obj","int(ADDR Object, int WindowHandle)");
  16. fast_threshold= dll.api("fast_threshold","int(ADDR Image, ADDR& Region, double MinGray, double MaxGray, int MinSize)");
  17. disp_region= dll.api("disp_region","int(ADDR DispRegions, int WindowHandle)");
  18. set_colored= dll.api("set_colored","int(int WindowHandle, int NumberOfColors)");
  19. set_color= dll.api("set_color","int(int WindowHandle, string Color)");
  20. boundary= dll.api("boundary","int(ADDR Region, ADDR& RegionBorder, string BoundaryType)");
  21. clip_region_rel= dll.api("clip_region_rel","int(ADDR Region, ADDR& RegionClipped, int Top, int Bottom, int Left, int Right)");
  22. dilation_circle= dll.api("dilation_circle","int(ADDR Region, ADDR& RegionDilation, double Radius)");
  23. reduce_domain= dll.api("reduce_domain","int(ADDR Image, ADDR Region, ADDR& ImageReduced)");
  24. edges_sub_pix= dll.api("edges_sub_pix","int(ADDR Image, ADDR& Edges, string Filter, double Alpha, int Low, int High)");
  25. segment_contours_xld= dll.api("segment_contours_xld","int(ADDR Contours, ADDR& ContoursSplit, string Mode, int SmoothCont, double MaxLineDist1, double MaxLineDist2)");
  26. count_obj= dll.api("count_obj","int(ADDR Objects, int& Number)");
  27. set_draw= dll.api("set_draw","int(int WindowHandle, string Mode)");
  28. select_obj= dll.api("select_obj","int(ADDR Objects, ADDR& ObjectSelected, int Index)");
  29. //主要是下面这个函数
  30. T_get_contour_global_attrib_xld= dll.api("T_get_contour_global_attrib_xld","int(ADDR Contour, pointer Name, pointer Attrib)");
  31. fit_circle_contour_xld= dll.api("fit_circle_contour_xld","int(ADDR Contours, string Algorithm, int MaxNumPoints, double MaxClosureDist, int ClippingEndPoints, int Iterations, double ClippingFactor, double& Row, double& Column, double& Radius, double& StartPhi, double& EndPhi, string& PointOrder)");
  32. gen_circle_contour_xld= dll.api("gen_circle_contour_xld","int(ADDR& ContCircle, double Row, double Column, double Radius, double StartPhi, double EndPhi, string PointOrder, double Resolution)");
  33. set_line_width= dll.api("set_line_width","int(int WindowHandle, double Width)");
  34. //下面是对tuple的一些操作
  35. F_create_tuple= dll.api("F_create_tuple","void(pointer T, int length)");
  36. F_create_tuple_i= dll.api("F_create_tuple_i","void(pointer T, int val)");
  37. F_create_tuple_s=dll.api("F_create_tuple_s","void(pointer T, string val)");
  38. F_get_s=dll.api("F_get_s","string(pointer T, int index)");
  39. F_set_s=dll.api("F_set_s","void(pointer T, string val,int index)");
  40. F_get_i=dll.api("F_get_i","int(pointer T, int index)");
  41. F_create_tuple_d=dll.api("F_create_tuple_d","void(pointer T, double val)");
  42. F_create_tuple_type=dll.api("F_create_tuple_type","void(pointer T, int length, int type)");
  43. F_destroy_tuple=dll.api("F_destroy_tuple","void(pointer T)");


  44. console.open();
  45. mainForm.button.oncommand = function(id,event){
  46.      
  47.     var ret,Image = read_image(0,"res/double_circle");
  48.     var ret,width,height = get_image_size(Image,0,0);
  49.     var ret,Hwindow = open_window(0,0,width,height,mainForm.picturebox.hwnd,"visible", "",0);
  50.     var ret = disp_obj(Image,Hwindow);
  51.     //win.delay(1000)
  52.     var ret,Region = fast_threshold(Image,0,0,120,7);
  53.     set_colored(Hwindow,6);
  54.     disp_region(Region,Hwindow)
  55.     //win.delay(1000)
  56.     var ret,RegionBorder = boundary(Region,0,"inner");
  57.     var ret,RegionClipped = clip_region_rel(RegionBorder,0,5,5,5,5);
  58.     var ret,RegionDilation = dilation_circle(RegionClipped,0,2.5);
  59.     var ret,ImageReduced = reduce_domain(Image,RegionDilation,0);
  60.     var ret = disp_obj(ImageReduced,Hwindow);
  61.     //win.delay(1000)
  62.     var ret,Edges = edges_sub_pix(ImageReduced,0,"canny",2,20,60);
  63.     var ret = disp_obj(Edges,Hwindow);
  64.     //win.delay(1000)
  65.     var ret,ContoursSplit = segment_contours_xld(Edges,0,"lines_circles",5,4,3);
  66.     //var ret = disp_obj(ContoursSplit,Hwindow);
  67.     var ret = disp_obj(Image,Hwindow);
  68.     var ret,Number = count_obj(ContoursSplit,0);
  69.     //mainForm.snumber.text = Number;
  70.     set_draw(Hwindow,"margin");
  71.     set_color(Hwindow,"orange red");
  72.     set_line_width(Hwindow,4.0);
  73.     console.log("开始循环")
  74.     win.delay(1000)
  75.     for(i=1;Number;1){
  76.         var ret,ObjectSelected = select_obj(ContoursSplit,0,i);
  77.         //这里定义了需要使用的tuple元组
  78.         var nametuple = raw.buffer(100);
  79.         F_create_tuple_s(nametuple,"cont_approx");
  80.         var Attribtuple = raw.buffer(100);
  81.         F_create_tuple(Attribtuple,0);
  82.         F_destroy_tuple(Attribtuple);
  83.         //var Patt = raw.toPointer(Attribtuple)
  84.         
  85.         console.log("第"++i++"次循环开始")
  86.         win.delay(1000)
  87.         //下面这个引用函数老是报错: raw callback 内存错误
  88.         var ret,Attrib = T_get_contour_global_attrib_xld(ObjectSelected,nametuple,Attribtuple);
  89.         //if(Attrib > 0){
  90.              console.log("第"++i++"次循环结束")
  91.             win.delay(1000)
  92.         //}
  93.     }
  94. }

  95. mainForm.enableDpiScaling();
  96. mainForm.show();

  97. return win.loopMessage();
复制代码


工程下载地址: https://pan.baidu.com/s/19PlTCUTAfCrGUl_1IjNjxA

38

主题

129

回帖

1045

积分

荣誉会员

积分
1045
 楼主| 发表于 2018-3-31 01:05:50 | 显示全部楼层
为了判断是不是第三个参数错误导致的, 我增加了一个包含tuple参数的dll函数进行测试
  1. T_query_contour_global_attribs_xld= dll.api("T_query_contour_global_attribs_xld","int(ADDR Contour, pointer Attrib)");
复制代码

上面的函数是: Return the names of the defined global attributes of an XLD contour
即: 返回定义的全局属性名称
于是,我将主要代码更改为:
  1. for(i=1;Number;1){
  2.         var ret,ObjectSelected = select_obj(ContoursSplit,0,i);
  3.         //这里定义了需要使用的tuple元组
  4.         
  5.         var Attribtuple = raw.buffer(1000);
  6.         F_create_tuple(Attribtuple,0);
  7.         
  8.         console.log("第"++i++"次循环开始")
  9.         win.delay(1000)
  10.         T_query_contour_global_attribs_xld(ObjectSelected,Attribtuple);
  11.         var ret = Mlength_tuple(Attribtuple);
  12.                 console.varDump(ret)
  13.                 var ret = F_get_s(Attribtuple,0)
  14.                 console.varDump(ret)
  15.                 win.delay(1000)
  16.                 console.log("第"++i++"次循环结束")
  17. }
复制代码

运行发现, 完全可以获取到这个全局属性名, 说明 作为输出参数 (pointer Attrib) 这样声明是没有问题的
那么如果我把F_create_tuple(Attribtuple,0);这句话也注释掉,会怎样呢?
结果是, 还是可以正确获取到, 那么说明dll声明里为pointer的输出类型的话, 是不需要对指针进行强制tuple转换的,
也就是说, 我们前面那个函数报内存错误, 不是由于第三个参数导致的.
而且, 那个函数的第三个参数声明, 同样也应该是pointer , 使用的时候只需定义为raw.buff()指针即可.

那么, 上面的函数报内存错误, 就是第二个函数引起的了.
缩小了排查范围.
明天继续测试, 希望能找到解决办法.
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|aardio.com|aardio 官方社区 ( 皖ICP备09012014号 )

GMT+8, 2024-12-5 15:28 , Processed in 0.079651 second(s), 22 queries .

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表