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#
安装完成后用以下命令测试是否安装成功
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动态库传结构体详细教程的更多相关文章
- Delphi调用C# 编写dll动态库
Delphi调用C# 编写dll动态库 编写C#dll的方法都一样,首先在vs2005中创建一个“类库”项目WZPayDll, using System.Runtime.InteropServices ...
- java使用JNA框架调用dll动态库
这两天了解了一下java调用dll动态库的方法,总的有三种:JNI.JNA.JNative.其中JNA调用DLL是最方便的. ·JNI ·JNA ·JNative java使用 JNI来调用dll动态 ...
- Delphi - Windows系统下,Delphi调用API函数和7z.dll动态库,自动把文件压缩成.tar.gz格式的文件
项目背景 应欧美客户需求,需要将文件压缩成.tar.gz格式的文件,并上传给客户端SFTP服务器. 你懂的,7-Zip软件的显著特点是文件越大压缩比越高,在Linux系统上相当于我们Windows系统 ...
- Java调用dll动态库
最近项目里使用java调用dll动态库,因此研究了一下这方面的东西. 使用的工具包如下 <dependency> <groupId>net.java.dev.jna</g ...
- Golang调用windows下的dll动态库中的函数
Golang调用windows下的dll动态库中的函数 使用syscall调用. package main import ( "fmt" "syscall" & ...
- Golang调用windows下的dll动态库中的函数 Golang 编译成 DLL 文件
Golang调用windows下的dll动态库中的函数 package main import ( "fmt" "syscall" "time&quo ...
- 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 ...
- 2017.10.29 C/C++/C#程序如何打成DLL动态库
C/C++程序如何打成DLL动态库: **1.在VS中新建main.h,添加如下内容:** extern "C" _declspec(dllexport) int onLoad() ...
- C/C++/C#程序如何打成DLL动态库
C/C++程序如何打成DLL动态库:1.在VS中新建main.h,添加如下内容:extern "C" _declspec(dllexport) int onLoad(); 2.新建 ...
- .NET 使用 MySql.Data.dll 动态库操作MySql的帮助类--MySqlHelper
.NET 使用 MySql.Data.dll 动态库操作MySql的帮助类--MySqlHelper 參考演示样例代码,例如以下所看到的: /// <summary> /// MySql ...
随机推荐
- AI PC两年要大卖1亿台!就靠它了
Intel在中国北京召开了主题为"AI无处不在,创芯无所不及"的2023Intel新品发布会暨AI技术创新派对,正式发布了代号为"Meteor Lake"的面向 ...
- 营销(marketing)、推广(Promotion)和 运营(Operation)的概念分别是什么?
首先要明确的原则: 1.你得承认"讨论任何事情之前不弄清楚概念定义就是耍流氓" 2.你得承认"由于每个人的经验学识和理解力的不同,我们常对概念定义产生分歧" 3 ...
- T406696 『STA - R4』冰红茶 题解
题目链接:冰红茶 比较有意思的套路题(前提是接触过) 首先,一个最基本的线段树包含两种操作的板子要会,分别为区间赋值与区间加,同时维护区间最值.这个挺简单的,区间赋值优先级高于区间加,可以将区间加覆盖 ...
- P9816 少项式复合幂 题解
题目链接:少项式复合幂 注意到题目的模并不是很大,我们考虑两个核心的性质. \(f(f(x)) \bmod p=f(f(x) \bmod p) \bmod p\),证明直接代入 \(f(x)\) 进去 ...
- 《ASP.NET Core 与 RESTful API 开发实战》-- (第7章)-- 读书笔记(上)
第 7 章 高级主题 7.1 缓存 缓存是一种通过存储资源的备份,在请求时返回资源备份的技术.ASP.NET Core 支持多种形式的缓存,既支持基于 HTTP 的缓存,也支持内存缓存和分布式缓存,还 ...
- 思维分析逻辑 4 DAY
目录 竞品分析 波特五力模型 竞品分析步骤 分析目的 对比分析 初步结论 活动营销分析 用户增长分析 用户增长基本模型 渠道思维(前期) 用户思维(中期) ROI思维(后期) 增长思维 北极星指标:一 ...
- 浅谈 2-SAT
SAT 是适定性(Satisfiability)问题的简称.一般形式为 k - 适定性问题,简称 k-SAT.而当 \(k>2\) 时该问题为 NP 完全的.所以我们只研究 \(k=2\) 的情 ...
- 【OpenGL ES】绘制三角形
1 前言 1.1 设置顶点属性 顶点有位置.颜色等属性,可以通过 glVertexAttribPointer 设置顶点的属性. void glVertexAttribPointer( int in ...
- oracle exp/imp命令使用parfile实现参数文件调用
优先使用数据泵(expdp/impdp)方式,更高效,问题少. 关于exp/imp工具的使用请参考我的另一篇文章: https://blog.csdn.net/IndexMan/article/det ...
- SpringCloud SpringBoot 组件使用:使用Nacos作为服务的注册中心和配置中心
基础篇 一.什么是Nacos? 官方介绍是这样的: Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您实现动态服务发现.服务配置管理.服务及流量管理. Na ...