开发日记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#

安装完成后用以下命令测试是否安装成功

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

传字符串指针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;

aardio调用c语言dll动态库传结构体详细教程的更多相关文章

  1. Delphi调用C# 编写dll动态库

    Delphi调用C# 编写dll动态库 编写C#dll的方法都一样,首先在vs2005中创建一个“类库”项目WZPayDll, using System.Runtime.InteropServices ...

  2. java使用JNA框架调用dll动态库

    这两天了解了一下java调用dll动态库的方法,总的有三种:JNI.JNA.JNative.其中JNA调用DLL是最方便的. ·JNI ·JNA ·JNative java使用 JNI来调用dll动态 ...

  3. Delphi - Windows系统下,Delphi调用API函数和7z.dll动态库,自动把文件压缩成.tar.gz格式的文件

    项目背景 应欧美客户需求,需要将文件压缩成.tar.gz格式的文件,并上传给客户端SFTP服务器. 你懂的,7-Zip软件的显著特点是文件越大压缩比越高,在Linux系统上相当于我们Windows系统 ...

  4. Java调用dll动态库

    最近项目里使用java调用dll动态库,因此研究了一下这方面的东西. 使用的工具包如下 <dependency> <groupId>net.java.dev.jna</g ...

  5. Golang调用windows下的dll动态库中的函数

    Golang调用windows下的dll动态库中的函数 使用syscall调用. package main import ( "fmt" "syscall" & ...

  6. Golang调用windows下的dll动态库中的函数 Golang 编译成 DLL 文件

    Golang调用windows下的dll动态库中的函数 package main import ( "fmt" "syscall" "time&quo ...

  7. Qt打开外部程序和文件夹需要注意的细节(Qt调用VC写的动态库,VC需要用C的方式输出函数,否则MinGW32编译过程会报错)

    下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this ...

  8. 2017.10.29 C/C++/C#程序如何打成DLL动态库

    C/C++程序如何打成DLL动态库: **1.在VS中新建main.h,添加如下内容:** extern "C" _declspec(dllexport) int onLoad() ...

  9. C/C++/C#程序如何打成DLL动态库

    C/C++程序如何打成DLL动态库:1.在VS中新建main.h,添加如下内容:extern "C" _declspec(dllexport) int onLoad(); 2.新建 ...

  10. .NET 使用 MySql.Data.dll 动态库操作MySql的帮助类--MySqlHelper

    .NET 使用 MySql.Data.dll 动态库操作MySql的帮助类--MySqlHelper 參考演示样例代码,例如以下所看到的: /// <summary> /// MySql ...

随机推荐

  1. Win12不会取代Win11!真正目标是Google

    Windows 11之后自然应该是Windows 12,但这一次不太一样. 据多个消息源确认,Windows的下一个重大版本将不会是Windows 11的直接升级版,而是更专注于云和Web,同时大力接 ...

  2. 源代码安装Nginx和PHP

    源代码安装Nginx和PHP 一.安装前准备: 有些工具在安装Nginx必备.譬如gcc用来编译C程序,gcc-c++ 用来编译C++程序,wget用来从网络下载文件. [root@localhost ...

  3. ElasticSearch7.3学习(十二)----type底层结构及弃用原因

    1.type是什么 type,是一个index中用来区分类似的数据的.类似的数据,但是可能有不同的fields,而且有不同的属性来控制索引建立.分词器.field的value. 在底层的lucene中 ...

  4. ArrayList中的遍历删除

    ArrayList 中的遍历删除 在代码编写过程中经常会遇到这样的要求:遍历一个线性表,要求只遍历一遍(时间复杂度\(O(n)\)),删除符合指定条件的元素,且要求空间复杂度 \(O(1)\). 例如 ...

  5. 【Unity3D】粒子系统ParticleSystem

    1 简介 ​ 拖尾(TrailRenderer).线段渲染器(LineRenderer).粒子系统(ParticleSystem)是 Unity3D 提供的三大特效,其中粒子系统的功能最为强大,特效也 ...

  6. Js中Symbol对象

    Js中Symbol对象 ES6引入了一种新的基本数据类型Symbol,表示独一无二的值,最大的用法是用来定义对象的唯一属性名,Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方 ...

  7. 承前启后,Java对象内存布局和对象头

    承前启后,Java对象内存布局和对象头 大家好,我是小高先生.在我之前的一篇文章<并发编程防御装-锁(基础版)>中,我简要介绍了锁的基础知识,并解释了为什么Java中的任何对象都可以作为锁 ...

  8. c# 代码操作ftp服务器文件

    好久不见,我又回来了.给大家分享一个最近c#代码操作ftp服务器的代码示例 1 public abstract class FtpOperation 2 { 3 /// <summary> ...

  9. Java设计模式-桥接模式Bridge

    传统模式 案例 要求对不同手机类型的不同品牌实现操作编程(比如:开机.关机.上网,打电话等),如图: 类图 问题 扩展性问题(类爆炸),如果我们再增加手机的样式(旋转式),就需要增加各个品牌手机的类, ...

  10. image could not be accessed on a registry to record its digest

    问题说明: 在管理节点执行docker stack xxx 方式运行服务,报如题错误. 问题原因: docker swarm运行需要一个镜像仓库才行,所有节点都去这个仓库统一镜像. 来看下官方的解释: ...