开发日记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. AI PC两年要大卖1亿台!就靠它了

    Intel在中国北京召开了主题为"AI无处不在,创芯无所不及"的2023Intel新品发布会暨AI技术创新派对,正式发布了代号为"Meteor Lake"的面向 ...

  2. 营销(marketing)、推广(Promotion)和 运营(Operation)的概念分别是什么?

    首先要明确的原则: 1.你得承认"讨论任何事情之前不弄清楚概念定义就是耍流氓" 2.你得承认"由于每个人的经验学识和理解力的不同,我们常对概念定义产生分歧" 3 ...

  3. T406696 『STA - R4』冰红茶 题解

    题目链接:冰红茶 比较有意思的套路题(前提是接触过) 首先,一个最基本的线段树包含两种操作的板子要会,分别为区间赋值与区间加,同时维护区间最值.这个挺简单的,区间赋值优先级高于区间加,可以将区间加覆盖 ...

  4. P9816 少项式复合幂 题解

    题目链接:少项式复合幂 注意到题目的模并不是很大,我们考虑两个核心的性质. \(f(f(x)) \bmod p=f(f(x) \bmod p) \bmod p\),证明直接代入 \(f(x)\) 进去 ...

  5. 《ASP.NET Core 与 RESTful API 开发实战》-- (第7章)-- 读书笔记(上)

    第 7 章 高级主题 7.1 缓存 缓存是一种通过存储资源的备份,在请求时返回资源备份的技术.ASP.NET Core 支持多种形式的缓存,既支持基于 HTTP 的缓存,也支持内存缓存和分布式缓存,还 ...

  6. 思维分析逻辑 4 DAY

    目录 竞品分析 波特五力模型 竞品分析步骤 分析目的 对比分析 初步结论 活动营销分析 用户增长分析 用户增长基本模型 渠道思维(前期) 用户思维(中期) ROI思维(后期) 增长思维 北极星指标:一 ...

  7. 浅谈 2-SAT

    SAT 是适定性(Satisfiability)问题的简称.一般形式为 k - 适定性问题,简称 k-SAT.而当 \(k>2\) 时该问题为 NP 完全的.所以我们只研究 \(k=2\) 的情 ...

  8. 【OpenGL ES】绘制三角形

    1 前言 1.1 设置顶点属性 ​ 顶点有位置.颜色等属性,可以通过 glVertexAttribPointer 设置顶点的属性. void glVertexAttribPointer( int in ...

  9. oracle exp/imp命令使用parfile实现参数文件调用

    优先使用数据泵(expdp/impdp)方式,更高效,问题少. 关于exp/imp工具的使用请参考我的另一篇文章: https://blog.csdn.net/IndexMan/article/det ...

  10. SpringCloud SpringBoot 组件使用:使用Nacos作为服务的注册中心和配置中心

    基础篇 一.什么是Nacos? 官方介绍是这样的: Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您实现动态服务发现.服务配置管理.服务及流量管理. Na ...