添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

首先我们VS界面左上角: 文件(F) -》 新建项目 -》 visual C++ -》 windows 桌面 -》 动态链接库(DLL)
在这里插入图片描述
得到以下界面
在这里插入图片描述

我们新建一个头文件: <Dll1.h>
在这里插入图片描述

我们在Dll1.cpp里面编写代码
1.需要用到头文件<Dll1.h>和 <Windows.h>
2.在函数前面 返回值类型 后面加上 “__stdcall” 也就是宏“WINAPI”

  • 微软解释:
    调用约定用于调用Win32 API函数。被调用者会清除堆栈,因此编译器会生成vararg函数。使用这种调用约定的函数需要一个函数原型。下面的列表显示了这个调用约定的实现。

  • 符合国人的解释:
    几乎我们写的每一个WINDOWS API函数都是__stdcall类型的。
    首先,需要了解两者之间的区别: WINDOWS的函数调用时需要用到栈(STACK,一种先入后出的存储结构)。
    当函数调用完成后,栈需要清除,【这里就是问题的关键】,如何清除??
    如果我们的函数使用了_cdecl,那么栈的清除工作是由调用者,用COM的术语来讲就是客户来完成的。这样带来了一个棘手的问题,不同的编译器产生栈的方式不尽相同,那么调用者能否正常的完成清除工作呢?答案是不能。 如果使用__stdcall,上面的问题就解决了,函数自己解决清除工作。所以,在跨(开发)平台的调用中,我们都使用__stdcall(虽然有时是以WINAPI的样子出现)。那么为什么还需要_cdecl呢?当我们遇到这样的函数如fprintf()它的参数是可变的,不定长的,被调用者事先无法知道参数的长度,事后的清除工作也无法正常的进行,因此,这种情况我们只能使用_cdecl。到这里我们有一个结论,如果你的程序中没有涉及可变参数,最好使用__stdcall关键字。

// Dll1.cpp : 定义 DLL 应用程序的导出函数。
#include "Dll1.h"
#include "stdafx.h"
#include <Windows.h>
//两数相加
int WINAPI add(int n1, int n2)
    return n1 + n2;

我们在 <Dll1.h> 头文件里:声明函数

#pragma once
int WINAPI add(int n1, int n2);

导出函数:有 3种 导出方法,头文件和cpp都要改
1.第一种:在函数返回值类型前面加上 __declspec(dllexport)

__declspec(dllexport) int WINAPI add(int n1, int n2);

得到效果如图:
在这里插入图片描述
由于C++支持函数重载,国人称之为 “名称粉碎机制” 所以导出函数名会改变,第三方调用的时候需带如图名称,显然不是很适合咱

2.第二种:在函数返回值类型前面加上 extern “C” __declspec(dllexport) 指定该函数是个C语言的函数

extern "C" __declspec(dllexport) int WINAPI add(int n1, int n2);

得到效果如图:
在这里插入图片描述
第三方调用的时候需带如图名称了,显然也不是很合适
3.第三种:新建 “def” 文件实现函数导出

在这里插入图片描述
“Dll1.def ” 写入代码:

LIBRARY
EXPORTS

.def 文件中的第一条 LIBRARY 语句不是必须的,但LIBRARY 语句后面的 DLL 的名称必须正确,即与生成的动态链接库的名称必须匹配。此语句将 .def 文件标识为属于 DLL。链接器将此名称放到 DLL 的导入库中。

EXPORTS语句列出名称,可能的话还会列出 DLL 导出函数的序号值。通过在函数名的后面加上 @ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从 1 到 N,其中 N 是 DLL 导出函数的个数。
在这里插入图片描述
得到效果如图:

最后编写好如下3个文件及内容:
在这里插入图片描述
此时我们就可以编译代码给第三方程序调用了;

C++ 调用例子

1.将DLL放到运行目录

// TEST.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "pch.h"
#include <iostream>
#include <Windows.h>
//定义一个函数指针返回值和参数必须和原函数一致,声明该函数是 WINAPI 自己释放栈的
typedef int(WINAPI *ADD)(int n1, int n2);
int main()
    //LoadLibrary函数将指定的可执行模块映射到调用进程的地址空间。L表示宽字符的DLL名称
    HMODULE hDll = LoadLibrary(L"Dll1.dll");
    if (!hDll)
        std::cout << "error LoadLibrary";
        return -1;
    //GetProcAddress函数从指定的动态链接库(DLL)中检索导出的函数或变量的地址。
    ADD add = (ADD)GetProcAddress(hDll,"add");
    //调用并输出返回值
    std::cout << add(6,9); 
    //释放句柄
    FreeLibrary(hDll);

易语言调用例子:

1.将DLL放到运行目录

.版本 2
.DLL命令 add, 整数型, "Dll1.dll", "add"
    .参数 a, 整数型
    .参数 b, 整数型
调试输出 (add (3, 4))
                    项目要求创建DLL第一步:第二步:第三步:第四步:第五步:1.用C++编写一个动态链接库(DLL)供第三方调用2.开发环境VS2017创建DLL第一步:首先我们VS界面左上角:文件(F)-》新建项目-》visual C++ -》windows 桌面 -》动态链接库(DLL)得到以下界面第二步:我们新建一个头文件:&lt;Dll1.h&gt;第三步:我们在Dll1.cpp里...
				
NVTemp.DLL可获取NVIDIA显卡的温度,int GetTemperature(unsigned long temperature[]) 可以在能够调用DLL的语言中使用。 在C#调用: [DllImport("NvTemp.dll", EntryPoint = "GetTemperature")] public static extern bool GetTemperature(ulong[] temp); temp = new ulong[1]; r = GetTemperature(temp); 在temp[0]中为温度。
http://blog.csdn.net/solstice/archive/2010/01/16/5196544.aspx 多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间 虽然 RDTSC 废掉了,性能测试用的高精度计时还是有办法的 [2],在 Windows 用 QueryPerformanceCounter 和 QueryPerformanceFrequency,Linu
今天在https://blog.csdn.net/bopzhou/article/details/6063163上看到了如何获取一个数组的长度,收藏一下。 #include &amp;lt;iostream&amp;gt; template &amp;lt;typename T&amp;gt; int length(const T&amp;amp; arr) { return sizeof(arr) / sizeof(arr[0]);...
      动态链接库的调用方式有两种,一种是静态调用,一种是动态调用。静态调用dll比较简单,将.dll,.h,.lib放在工程下,在工程里使用下列格式包含,就可以直接使用了。 #pragma comment(lib,"XXX")      而动态调用dll就有些复杂了,但动态调用仅需要dll文件就可以,不需要包含上述lib。调用之前需要构造一个函数类型,比如我需要调用VCI_StartC...
并不是所有的语言都支持_cdcel调用规则,但是都支持_sdtcall调用规则, 假如你用VC做了一个DLL,导出了某些函数,如果你想这个DLL被其他语言也能调用的话,VB.DEPHI.PB..你的把他的调用约定声明为__stdcallwindows   api都是_stdcall调用规则, 函数调用约定确定一个程序如何实现一个函数调用及参数如何传递。在单一语言程序中,调用约定几乎总是正确
本文参考http://blog.csdn.net/sinat_27382047/article/details/70339455以及峰神的网站~~~~~~膜一发​ 本文提供了在Visual Studio 2017中利用masm依赖,在c++项目中编写、编译、运行汇编语言的方法。本文兼容Visual Studio 2012及以上版本。 新建空编项目 在2017最新版里,新建控制台应用 2.易语言中的函数名可能会被编译器修改,需要使用工具查看真实的函数名。 3.在C语言中使用LoadLibrary函数加载DLL,使用GetProcAddress函数获取函数地址,然后可以直接调用。 下面是一个简单的例子: 假设我们有一个由易语言编写DLL,其中有一个函数Add,功能是将两个整数相加并返回结果。 首先,我们需要在易语言中将这个函数导出为stdcall方式,代码如下: Function Add Alias "_Add@8"(a As Long, b As Long) Export As Long Return a + b End Function 注意,函数名被编译器修改为"_Add@8"。 接下来,在C语言中调用这个DLL,代码如下: #include <windows.h> #include <stdio.h> typedef int (*AddFunc)(int, int); int main() HMODULE dll = LoadLibrary("test.dll"); if (dll == NULL) { printf("Load DLL failed!\n"); return 0; AddFunc add = (AddFunc)GetProcAddress(dll, "_Add@8"); if (add == NULL) { printf("Get function address failed!\n"); return 0; int result = add(1, 2); printf("Result: %d\n", result); FreeLibrary(dll); return 0; 我们首先使用LoadLibrary函数加载DLL,然后使用GetProcAddress函数获取函数地址,注意函数名需要加上前缀"_"和后缀"@8"。最后,我们就可以直接调用这个函数了。 注意,在使用完DLL后,需要使用FreeLibrary函数释放DLL的句柄,否则会导致内存泄漏。
CSDN-Ada助手: 恭喜你第13篇博客的发布!标题看起来很有趣且实用。通过adb控制安卓手机实现紧急通知,这是一个非常有用的功能。你的博客内容一定很详细,能够帮助读者了解如何操作。 在下一步的创作中,我建议你可以考虑分享一些关于adb控制安卓手机其他实用功能的内容。例如,如何通过adb进行文件管理、安装应用程序等等。这些主题也会吸引更多读者的兴趣,并且让你的博客变得更加全面。 继续保持创作的热情,我期待着你未来更多精彩的博客! C++ 实现类 反射 类名获取对象 qq_45886634: 仅仅实现了对CReflectBase类型的生成,假如你子类带了数据成员,你怎么办? C++ 实现 类似 c# 扩展方法 YNStong: 你去用汇编语言把那样快,按你这思想c#,java语言都不该出现在这个世界 记录 Wireshark lua 5.2.4 插件 调用 C/C++ DLL 动态库 的心得 YNStong: 应该是你dll不规范 你源码放出来看看 记录 Wireshark lua 5.2.4 插件 调用 C/C++ DLL 动态库 的心得 hhwals: 大佬,插件不报错,加载插件wireshark就自动关闭了,请问知道怎么解决吗?