如何用AU3调用自己用VC++写的dll函数

简介: 这问题困扰我一个上午了,终于找到原因了,不敢藏私,和大家分享一下。 大家都知道,AU3下调用dll文件里的函数是很方便的,只要一个dllcall语句就可以了。 比如下面这个: $result = DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "若干文字", "str", "若干标题", "int", 0) 复制代码 就是调用user32.dll文件之中的MessageBox函数,创建一个窗口。

这问题困扰我一个上午了,终于找到原因了,不敢藏私,和大家分享一下。 大家都知道,AU3下调用dll文件里的函数是很方便的,只要一个dllcall语句就可以了。 比如下面这个:

  1. $result = DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "若干文字", "str", "若干标题", "int", 0)
复制代码

就是调用user32.dll文件之中的MessageBox函数,创建一个窗口。 但是如果要调用自己用vc++(我用的是vs2010)编写的dll文件之中的函数,似乎这样简单地使用就不会起作用,比如下面这个名叫dll.cpp的源码文件(用vs2010的dll模板建立,编译之后生成名为dll.dll的动态链接库),为了清晰起见,我将无关紧要的代码和注释去掉了,主要就一个很简单的求和函数:

  1. ...
  2. int dlladd(int a, int b)
  3. {
  4.         return a+b;
  5. }
复制代码

对应的dll.h文件中该函数的声明为:

  1. _declspec(dllexport) int dlladd(int a, int b);
复制代码

这样生成的dll.dll在引用和链接之后可以被vc++程序以dlladd的函数名正常调用,但是在au3之中,这样调用(调用之前别忘记把dll.dll文件拷贝到au3程序所在的目录):

  1. $result = DllCall("dll.dll", "int", "dlladd","int", 12, "int", 12)
复制代码

却无法正常使用。 原因有两个: 一是,c++支持重载,所以如果不做说明,编译生成的dll文件之中函数名字是会改变的,VC++程序会自动找到改名之后的函数,但是au3却无法找到,使用autoit3中文工具箱里自带的dll查看工具depends,查看dll.dll之中的导出函数, acn.jpg 可见dlladd被改名为类似“?dlladd@@YAHHHHH@z”这样的奇怪名字acn2.jpg 这时候可以用这样的方式在au3之中调用:

  1. $result = DllCall("dll.dll", "int", "?dlladd@@YAHHHHH@z","int", 12, "int", 12)
复制代码

但这样未免太傻了,所以更好的办法是在dll.h文件之中加上extern关键字,表示这个将会被外部程序调用,于是vc++就不会自动将函数改名了:

  1. extern "C" _declspec(dllexport) int dlladd(int a, int b);
复制代码

当然也可以改dll.def文件 但是这样改了之后,还会出现错误,这就是第二个原因了,因为vc++的函数默认的调用方式为_cdecl,而au3默认的函数调用方式为_stdcall,所以还要在dllcall语句的函数返回值后面标注一下调用方式:

  1. $result = DllCall("dll.dll", "int:cdecl", "dlladd","int", 12, "int", 12)
复制代码

这样就可以正常调用自己编写的dll文件之中的函数了。 此外还要注意一下,返回值的问题,返回的$result其实是个数组,$result[0]之中才是存储函数的返回值的

目录
相关文章
|
7天前
|
编译器 C语言 C++
【C++初阶(九)】C++模版(初阶)----函数模版与类模版
【C++初阶(九)】C++模版(初阶)----函数模版与类模版
11 0
|
17天前
|
存储 缓存 C++
C++链表常用的函数编写(增查删改)内附完整程序
C++链表常用的函数编写(增查删改)内附完整程序
|
20天前
|
存储 安全 编译器
【C++】类的六大默认成员函数及其特性(万字详解)
【C++】类的六大默认成员函数及其特性(万字详解)
33 3
|
22天前
|
安全 程序员 C++
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
97 0
|
23天前
|
设计模式 安全 C++
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
70 2
|
24天前
|
安全 编译器 程序员
【C++ 泛型编程 高级篇】C++ 编程深掘:静态成员函数检查的艺术与实践
【C++ 泛型编程 高级篇】C++ 编程深掘:静态成员函数检查的艺术与实践
62 0
|
24天前
|
存储 安全 编译器
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
106 0
|
24天前
|
安全 算法 编译器
【C++中的const函数】何时与如何正确声明使用C++ const函数(三)
【C++中的const函数】何时与如何正确声明使用C++ const函数
26 0
|
24天前
|
安全 编译器 Linux
【C++中的const函数】何时与如何正确声明使用C++ const函数(二)
【C++中的const函数】何时与如何正确声明使用C++ const函数
27 0
|
24天前
|
安全 编译器 C++
【C++中的const函数】何时与如何正确声明使用C++ const函数(一)
【C++中的const函数】何时与如何正确声明使用C++ const函数
22 0