aardio调用c语言dll动态库传结构体详细教程

开发日记3.11

此篇用于记录发那科数控机床(Fanuc CNC)采集程序开发中,C语言写底层然后用aardio写窗口调用dll的摸索出来的类型对应和踩坑整理。
由于发那科提供的开发套件是C语言的,所以由C语言编写动态库供其他程序调用,窗口界面也可以使用python等其他程序,C代码可移植Linux平台,本篇为Win平台。
后续再录个视频做一些说明。
后续更新移植Linux方法和发那科机床二次开发记录记录整理。

安装mingw32

下载安装配置

官方地址下载安装:https://sourceforge.net/projects/mingw/
安装方法:https://blog.csdn.net/HandsomeHong/article/details/120803368
↑记得最后要添加一下环境变量
mingw64 编译32位失败,待继续研究。https://zhuanlan.zhihu.com/p/413181676#
如果官网下载太慢可以用我提供的备份:https://gitee.com/dvaloveu/lovedva/blob/master/blog_attachments/mingw-get-setup.exe
下载链接失效请私信或者文章最下方评论,QQ465318701 答案:没有 xixixi_0987@hotmail.com
安装完成后用以下命令测试是否安装成功
gcc --version
g++ --version

用aardio测试范例程序

打开范例-调用其他语言-GCC-C++
用这个范例测试,注意去除 -municode 这个编译选项,即可成功。
-municode 这个选项与 Unicode(UTF-16) 宽字符相关,是VC++编译器的选项,若使用mingw就没有这个选项,处理宽字符用别的宽字符类型。
↑个人建议C语言编写dll库时不使用宽字符,在外部调用的时候封装返回结果再使用中文枚举类封装展示。

aardio中调用dll

var dll = raw.loadDll($"\cpp.dll",,"cdecl"); //必须要放在aar工程目录下
console.log("dll调用结果:",dll.hello())

C语言函数封装和编译

函数声明

编写可以被DLL导出,被其他程序调用的函数,使用宏来控制是否导出为可被外部调用的方法

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT
#endif

函数声明写法

DLL_EXPORT int hello();
DLL_EXPORT int connectCNC(char *str, unsigned short port,  long timeout, unsigned short *FlibHndl );

编译运行和编译DLL库

gcc main.c -o myprogram -L. -lfwlib32; .\myprogram.exe 
gcc main.c -o cpp.dll -DBUILD_DLL -L. -lfwlib32  -shared -s  -m32 -O2 -static -lgcc -lstdc++ ;mv cpp.dll .\aardio窗体\ -force

数据类型和结构体传参示例

根据手册里的API数据类型,按照对应的结构体传参,参考范例-调用其他语言-C语言-生成DLL,在线手册网站:https://bbs.aardio.com/doc/reference/

传字符串指针char *str和short整型指针

C函数

int connectCNC(char *str, unsigned short port,  long timeout, unsigned short *FlibHndl ){
    return cnc_allclibhndl3( str, port, timeout, FlibHndl);
}

aardio 对应写法

//声明 指针用结构体/表
var pthndl = {
		WORD x=666; 
	}
//传入结构体指针,接收返回值,和结构体数据
var ret,pthndl = dll.connectCNC("192.168.1.1",tonumber(mainForm.edit3.text),10,pthndl)
	console.log("返回值:",ret)
	console.log("连接cnc获取句柄:",pthndl.x)

传结构体参数

C函数和结构体定义

int getCNCStatus(unsigned short FlibHndl, ODBST * odbst){
    return cnc_statinfo( FlibHndl, odbst ) ;
}

typedef struct odbst {
    short   hdck ;      /* handl retrace status */
    short   tmmode ;    /* T/M mode */
    short   aut ;       /* selected automatic mode */
    short   run ;       /* running status */
    short   motion ;    /* axis, dwell status */
    short   mstb ;      /* m, s, t, b status */
    short   emergency ; /* emergency stop status */
    short   alarm ;     /* alarm status */
    short   edit ;      /* editting status */
} ODBST ;

对应aardio表定义和传参写法

//设备状态结构体定义
 ptODBST = {
	word    hdck ;      /* handl retrace status */
    word    tmmode ;    /* T/M mode */
    word    aut ;       /* selected automatic mode */
    word    run ;       /* running status */
    word    motion ;    /* axis, dwell status */
    word    mstb ;      /* m, s, t, b status */
    word    emergency ; /* emergency stop status */
    word    alarm ;     /* alarm status */
    word    edit ;      /* editting status */
}

ptODBST=cStruct.ptODBST   
var ret,ptODBST=dll.getCNCStatus(pthndl.x,ptODBST) 
mainForm.static16.text=enumPack.ODBSTrun[ptODBST.run];
console.log("getCNCStatus:",ret)

字符串数组 char[]传参

C函数和结构体定义

int getExePrgname( unsigned short h, ODBEXEPRG * odbexeprg){
    return cnc_exeprgname(h, odbexeprg); //获取文件名
}

typedef struct odbexeprg {
    char  name[36];     /* running program name */
    long  o_num;        /* running program number */
} ODBEXEPRG;            /*                        */

对应aardio表定义和传参写法

var ptODBEXEPRG= {
    byte name[36] ;     /* running program name */
    long64  o_num;        /* running program number */
} 

var ret,ptODBEXEPRG=dll.getExePrgname(pthndl.x,ptODBEXEPRG)
console.log("getExePrgname:",ret)
mainForm.static17.text=ptODBEXEPRG.name;
	

结构体嵌套和结构体数组传参

C函数和结构体定义

typedef struct iodbpsd {
    short   datano ;    /* data number */
    short   type ;      /* axis number */
    union {
        char    cdata ;     /* parameter / setting data */
        short   idata ;
        long    ldata ;
        REALPRM rdata ;
        char    cdatas[MAX_AXIS] ;
        short   idatas[MAX_AXIS] ;
        long    ldatas[MAX_AXIS] ;
        REALPRM rdatas[MAX_AXIS] ;
    } u ;
} IODBPSD ;

对应aardio表定义和传参写法

//读取公共参数结构体
MAX_AXIS=9;

ptiodbpsd ={
    word    datano ;    /* data number */
    word    typePra ;      /* axis number */
    union u= {
        byte    cdata ;     /* parameter / setting data */
        word   idata ;
        int     ldata ;
		rdata={
    			int prm_val;
    			int dec_val ;}
        byte    cdatas[]={length = MAX_AXIS;} ;
        word   idatas[]={length = MAX_AXIS;} ;
        int    ldatas[]={length = MAX_AXIS;} ;
        struct rdatas[] ={length = MAX_AXIS;
        {int prm_val;
    	 int dec_val ;}};
    }  ;
}  ;


cStruct.MAX_AXIS=3
ptiodbpsd=cStruct.ptiodbpsd
var ret,ptiodbpsd=dll.getParam(pthndl.x,6712,0, (4+4*3), ptiodbpsd )
mainForm.static18.text=ptiodbpsd.u.ldata;
posted @ 2024-02-29 23:02  韩大狗  阅读(72)  评论(0编辑  收藏  举报