如何用AU3调用自己用VC++写的dll函数
这问题困扰我一个上午了,终于找到原因了,不敢藏私,和大家分享一下。 大家都知道,AU3下调用dll文件里的函数是很方便的,只要一个dllcall语句就可以了。 比如下面这个:
- $result = DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "若干文字", "str", "若干标题", "int", 0)
复制代码
就是调用user32.dll文件之中的MessageBox函数,创建一个窗口。 但是如果要调用自己用vc++(我用的是vs2010)编写的dll文件之中的函数,似乎这样简单地使用就不会起作用,比如下面这个名叫dll.cpp的源码文件(用vs2010的dll模板建立,编译之后生成名为dll.dll的动态链接库),为了清晰起见,我将无关紧要的代码和注释去掉了,主要就一个很简单的求和函数:
- ...
- int dlladd(int a, int b)
- {
- return a+b;
- }
复制代码
对应的dll.h文件中该函数的声明为:
- _declspec(dllexport) int dlladd(int a, int b);
复制代码
这样生成的dll.dll在引用和链接之后可以被vc++程序以dlladd的函数名正常调用,但是在au3之中,这样调用(调用之前别忘记把dll.dll文件拷贝到au3程序所在的目录):
- $result = DllCall("dll.dll", "int", "dlladd","int", 12, "int", 12)
复制代码
却无法正常使用。 原因有两个: 一是,c++支持重载,所以如果不做说明,编译生成的dll文件之中函数名字是会改变的,VC++程序会自动找到改名之后的函数,但是au3却无法找到,使用autoit3中文工具箱里自带的dll查看工具depends,查看dll.dll之中的导出函数, 可见dlladd被改名为类似“?dlladd@@YAHHHHH@z”这样的奇怪名字。
这时候可以用这样的方式在au3之中调用:
- $result = DllCall("dll.dll", "int", "?dlladd@@YAHHHHH@z","int", 12, "int", 12)
复制代码
但这样未免太傻了,所以更好的办法是在dll.h文件之中加上extern关键字,表示这个将会被外部程序调用,于是vc++就不会自动将函数改名了:
- extern "C" _declspec(dllexport) int dlladd(int a, int b);
复制代码
当然也可以改dll.def文件 但是这样改了之后,还会出现错误,这就是第二个原因了,因为vc++的函数默认的调用方式为_cdecl,而au3默认的函数调用方式为_stdcall,所以还要在dllcall语句的函数返回值后面标注一下调用方式:
- $result = DllCall("dll.dll", "int:cdecl", "dlladd","int", 12, "int", 12)
复制代码
这样就可以正常调用自己编写的dll文件之中的函数了。 此外还要注意一下,返回值的问题,返回的$result其实是个数组,$result[0]之中才是存储函数的返回值的。
如何用AU3调用自己用VC++写的dll函数的更多相关文章
- 发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象
发现个delphi调用vc写的Dll中包括pchar參数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会执行报错,在之前随意加上条语句就不报错了奇怪! vc的DLL源代码地址 ...
- vc写的dll被mingw的g++编译引用
dll.cpp,用vc2017编译 #include <iostream>#include <windows.h> extern "C" __declspe ...
- 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 ...
- VS2013 VC++的.cpp文件调用CUDA的.cu文件中的函数
CUDA 8.0在函数的调用中方便的让人感动.以下是从网上学到的VC++的.cpp文件调用CUDA的.cu文件中的函数方法,和一般的VC++函数调用的方法基本没差别. 使用的CUDA版本为CUDA 8 ...
- Matlab与C++混合编程 1--在C++中调用自己写的matlab函数
在Visual Studio中使用C++中调用MATLAB程序 在matlab中可以通过mbuild工具将.m文件编译成dll文件供外部的C++程序调用,这样就可以实现matlab和C++混合编程的目 ...
- c++ c# java 调用 c++ 写的dll
1. vs 中新建win32 dll 项目 testdll 添加实现文件 test.cpp #include "stdafx.h" #include <ios ...
- php调用一个c语言写的接口问题
用php调用一个c语言写的soap接口时,遇到一个问题:不管提交的数据正确与否,都无法请求到接口 1.用php标准的soap接口去请求 2.拼接xml数据去请求 以上两种方式都不正确 解决办法:php ...
- Delphi调用C++写的dll示例
最近做一个读市民卡的项目,读卡器公司提供的读市民卡dll是用C++写的. 下面记录一些自己的心得,供需要的朋友参考. 声明dll函数要加上stdcall关键字,否则可能会报地址非法的错误. 代码: u ...
- java调用C/C++写的dll(转)
源:java调用C/C++写的dll Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台界面可以更快速,也能带来跨平台性. Java调用C/C++写好的DLL ...
随机推荐
- mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚
mysql的引擎常用的有两个,一个MyISAM,另一个是InnoDB,mysql默认的为MyISAM,而InnoDB才是支持事务的.所以一般需要修改下,如何修改就不说了. 事务需要依赖数据库,好久没使 ...
- 使用python实现归并排序、快速排序、堆排序
归并排序 使用分治法:分而治之 分: 递归地拆分数组,直到它被分成两对单个元素数组为止. 然后,将这些单个元素中的每一个与它的对合并,然后将这些对与它们的对等合并,直到整个列表按照排序顺序合并为止. ...
- 容器远程访问vnc--CentOS 6.8安装和配置VNC
对于用惯了WIN系统的朋友来说,没有图形化操作界面的Linux用起来实在太难受了.实际上,Linux也是有图形化操作界面的,这就是VNC.接下来本文将告诉大家如何在CentOS 6.8下安装和配置 V ...
- Coursera-吴恩达机器学习课程笔记-Week4+5
Neural networks non-linear hypotheses 非线性假设 Neural model:logistic unit 第一层 Input layer 最后一层 Outer la ...
- node.js+mysql环境搭建
https://www.jianshu.com/p/9b338095cbe8 node.js+mysql环境搭建 0x01 前言 随着html web技术的发展,和全栈式开发的需求,对于前端人员来讲, ...
- MySQL复制方法
MySQL的二进制日志,MySQL复制原理,MySQL主从模式搭建,MySQL双主模式搭建,MySQL级联模式搭建,MySQL半同步模式复制 一.二进制日志 1.概念 MySQL的二进制日志(bina ...
- iOS 增强程序健壮性 - - 使用 NullSafe 对 <null> 处理
在项目开发中,和服务端交互数据时,若服务端数据为空时,会出现 <null>,客户端解析时会 Crash,为了增强程序的健壮性,减少 Crash 的发生,可以使用 NullSafe 这个类别 ...
- 用apt-get解决dpkg过程中出现的依赖问题
dpkg命令不解决依赖问题,这点对新手很不友好 当使用dpkg -i *.deb 安装出现依赖问题的时候,可以尝试如下解决方法: apt-get -f -y install # 复制粘贴回车,inst ...
- LinkStack(链栈)
链栈即链式栈,也就是说我们不用再考虑空间的大小,可随心所欲的进行数据的插入/删除了.和顺序栈一样,仍然要保持其stack的特性,只在一端进行插入和删除,后进先出. (2018-02-14 代码更新) ...
- python中解方程
from sympy import * import numpy as np from numpy import linalg # 方程中的符号 x = Symbol('x') # 计算 result ...