范例

就以md5为例吧,首先去github搜索md5,选一个用c或者c++写的md5.

比如:https://github.com/chinaran/Compute-file-or-string-md5

我试了下用dev c++运行main_md5.c文件没什么问题。不过代码中计算文件md5的函数有点问题,先不管他,就演示一下计算字符串的。

Dev c++

首先说一下怎么用dev写一个dll

左上角->文件->新建->项目

选择DLL,下面选择C项目,项目名随便,就叫md5吧。然后选择一个空文件夹,即可创建dll项目
其他默认创建的dll.h文件内容:

#ifndef _DLL_H_
#define _DLL_H_#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endifDLLIMPORT void HelloWorld();#endif

这全部的代码其实就一句__declspec(dllexport) void HelloWorld();。声明HelloWorld函数并设置为导出函数。

将上面github地址代码下载下来,有三个文件md5.h、md5.c、main_md5.c。

将这三个文件中的内容稍微整合一下到dll.h、dll.c和dllmain.c中,下面有整合之后的代码

接着点上面的编译运行,编译完会弹出一个警告,没有主程序,不用管它,看项目的目录下的文件,已经有个md5.dll了


这个就是要用其他语言调用的dll,以Python为例(注意修改dll路径)

import ctypesdll = ctypes.CDLL("D:\\Android\\aaaa\\md5.dll")
md5 = dll.Compute_string_md5
md5.argtypes=[ctypes.c_char_p,  ctypes.c_uint, ctypes.c_char_p]
md5.restype = ctypes.c_int
msg = "123456"
result = ctypes.create_string_buffer(33)
print("运行是否成功(0成功):", md5(ctypes.c_char_p(msg.encode()), ctypes.c_uint(len(msg)), result))
print("字符串: %s, md5: %s" % (msg, result.value.decode()))

运行一下成功得到结果:

另外需要注意的是,如果在64位系统上dev C++编译的dll是64位的。需要使用64位Python才能调用。如果用的是32位则会报如下异常(32位dll同理)

Traceback (most recent call last):File "d:/Android/md5/md5.py", line 14, in <module>dll = ctypes.CDLL("D:\\Android\\aaaa\\md5.dll")File "C:\Anaconda\envs\py32\lib\ctypes\__init__.py", line 369, in __init__self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 不是有效的 Win32 应用程序。

百度了很久也没有发现dev c++怎么在64位系统编译32位dll,我试了直接更改右上角gcc的版本没用,换成32位的会报错。

代码地址:https://gitee.com/kanadeblisst/dev-c-dll-md5/

vs2017

要想编译32位的只能使用vs2017来编译了, 怎么安装就省略了,安装vs2019也行,可能某些操作不太一样。

左上角文件->新建项目

选择这个visual C++下的 Windows桌面下的具有导出项的动态链接库(记得修改上面的路径,不然你都不知道去哪找项目文件),如果没有这个选项可能你功能没有安装完全。我安装的时候是把Windows下的三个都勾选了,选择的社区版,只需要登录账号即可使用,功能对我来说足够用了。

代码基本上一样,复制到vs里就行了。就是不知道为什么他一定要pch.h这个头文件,改了名就报错。这篇文章说了:https://blog.csdn.net/weixin_43074474/article/details/89520392

我就直接将代码复制到pch.h和pch.cpp了,另外还有个地方需要修改__declspec(dllexport) 前要加上extern “C” ,不然导出函数的名字会变成其他了,前后加上了点东西(dev c++如果创建的是C++项目也是一样的)

用32位Python试了下上面的Python代码调用,没啥问题。

vs默认编译的是32位的dll,如果想编译64位的直接将x86改成x64再点击一次本地Windows调试器生成的dll就是64位的了

同样的代码vs编译的dll要比dev c++的小好多,到底是微软自家的IDE,不过dev c++用来测试一些简单的c/c++代码是真的方便。

更新

突然看到一篇文章:https://blog.csdn.net/songyi160/article/details/50754705

说将x86前的debug改为Release,我试了试,其他没变。就是编译的dll从原来的60K变成了14K,这变化也太大了吧

代码:https://gitee.com/kanadeblisst/vs2017-md5-dll

下一篇:编写aes加解密的dll

aardio调用dll

这个语言写桌面程序非常方便,我用的很顺手,就顺便说说这个怎么调用dll。注意:aardio只能调用32的dll

import console;var dll = raw.loadDll("D:\Android\Dll3\Debug\DLL3.dll",,"cdecl" );var md5 = dll.api("Compute_string_md5","int(string str,int len, string str)");
var s = "12345";
var str = raw.buffer(33);console.log("运行是否成功(0成功):", md5(s, #s, str))
console.log("md5结果: ", raw.tostring(str))console.pause(true);

看着是不是和Python代码差不了多少,步骤都是一样的。加载dll->声明函数原型->创建一个存放结果的缓冲区->调用函数->读取缓冲区的值。

更新

编码引发的小问题

md5 本身是对字节进行操作的,那么对字符串进行操作肯定要涉及编码问题了。c语言在Windows的默认编码是gbk,而Python3的默认编码是utf-8,而我试了所有的网站,对字符串计算md5用的编码都是utf8。

修改也很简单,可以不修改c代码,直接修改Python调用dll时的代码,只需要改传入的第二个参数,上面的代码用的是字符串的长度,其实应该传入字节串的长度,修改代码如下
md5(ctypes.c_char_p(msg.encode()), ctypes.c_uint(len(msg.encode())), result)

在python3中,'aaaa'.encode()等同于 'aaaa'.encode('utf-8'),所以并不需要更改编码,反倒是在c语言中将gbk编码变成utf8的很麻烦。

其实修改c代码也很简单,因为第二个参数长度是不必要的,可以直接通过第一个参数用strlen计算出来,所以在c代码中改一下也行。strlen计算的长度是从开头开始到遇到的第一个字节0,即’\0’,正好是需要的长度。

编译成Linux的so文件

我记得在哪里看到过这样一句话,so其实就是没有main函数的程序。

所以将上面的md5程序改成so很简单,只需要去掉dll 的代码,保留主要的pch.h和pch.cpp(在vs项目中我直接将md5的代码写在里面了),再把__declspec(dllexport)这个去掉,然后在Linux使用g++ -shared -fPIC -o md5.so pch.cpp。-o后面指定的是输出的so文件名,然后是需要编译的cpp文件。

用Python调用的代码不变,dll = ctypes.CDLL("/root/md5.so"),改成so的路径就行了。

不过怎么在64位Linux编译32位的so,我还没搜到。有些说加-m32参数,我试的时候报错了,大概意思是缺少某些32位的依赖库。

c/c++编写dll供其他语言调用相关推荐

  1. c语言调易语言dll,易语言DLL来返回文本供其他语言调用

    部分简介 在使用易语言与其他语言配合编程中,有时需要使用易语言的DLL来返回文本型的值,但是由于易语言本身文本型数据不能直接返回让其他语言使用(直接使用多次会崩溃).所以这里要使用一种转换的方式,是其 ...

  2. 易语言如何调用c dll文件,易语言调用C++写的DLL

    直接调用会弹出堆栈错误的信息,原因是VS默认是__cdcel方式,而易语言是__stdcall,所以调用约定不一致导致堆栈错误. 解决方案很简单,易语言声明DLL函数时"在库中对应命令名&q ...

  3. c++创建包含opencv的dll供C,C#调用

    最近做项目,需要将C++算法封装成dll,给C#调用,之前没接触过C#,现学一波,只做了dll并用C#测试了下,运行成功.记录下来过程,供大家参考. 编程环境:VS2013+opencv2.4.13 ...

  4. c 编译易语言dll文件,易语言调用DLL的问题(付dll文件,VC++编译的)

    AA直译器v1.02.rar (795.15 KB, 下载次数: 143) 2012-11-27 17:23 上传 点击文件名下载附件 dll说明: CE自动汇编直译器: AA引擎 各语言通用DLL ...

  5. C++代码封装成dll供C#中调用、调用dll无可用源

    C#工程不可以直接调用C++的头文件和Lib库等 所以在程序中C#需要调用的现象,先将C++的东西封装成动态链接库,再调用 若调用dll时显示:无可用源调用,说明导入的DLL路径不对. 静态库和动态库 ...

  6. qt编译c语言dll,QT编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)

    最近这阵子,接了个私活,封装一个开发包俗称的SDK给客户调用,查阅了不少人家的SDK,绝大部分用VC编写,并且VC6.0居多,估计也是为了兼容大量的XP用户及IE浏览器,XP自带了VC6.0运行库,因 ...

  7. .net core 调用c dll_Qt编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)

    一.前言 最近这阵子,接了个私活,封装一个开发包俗称的SDK给客户调用,查阅了很多人家的SDK,绝大部分用VC编写,而且VC6.0居多,估计也是为了兼容大量的XP用户及IE浏览器,XP自带了VC6.0 ...

  8. 易语言c调用,易语言调用C++编写的DLL

    511遇见网站最近在录制一套易语言编写DLL及调用和Hook,今天记录一下使用VS2015编写一个C++的Dll,易语言来调用. 步骤: 1.启动VS2015 2.创建工程 3.Visual C++ ...

  9. C++ 编写DLL文件给易语言调用

    摸索了两天了,终于解决了所有问题,在此跟大家分享. 需要三个文件,dll_demo.h.dll_demo.cpp.dll_dome.def 直接上代码: 头文件如下: 1 #ifndef _DLL_D ...

最新文章

  1. R语言使用ggplot2包的快速可视化函数qplot绘制分组分组点图(带状图)实战
  2. 脚本检测到文件特定词后做下一步动作 down restart
  3. matlab面向对象排序,matlab面向对象编程基础
  4. 修改mysql字符集 为utf8_修改mysql数据库字符集为UTF8的
  5. 【Java】对JTable里的元素进行排序
  6. 阿里云安装单机hbase
  7. C语言小知识---printf()函数
  8. Spring 实现发送电子邮件的两种方法
  9. Vue2.0进阶组件篇2 解析饿了么(spinner组件)
  10. 利用向日葵远程控制工具实现远程控制电脑
  11. 4款APP原型设计工具助你搞定移动应用设计!
  12. Japanese Student Championship 2019 Qualification B - Kleene Inversion(规律 + 快速乘)
  13. 无线网络打印机服务器安装步骤,网络打印机安装步骤
  14. Blowfish简介
  15. 【excel】QUARTILE.EXC V.S. QUARTILE.INC
  16. win10计算机全名恢复,详细教您win10强制进入恢复模式方法
  17. 操作系统简介及编程语言
  18. Linux简单的文件管理器设计,桌面应用|如何从 Linux 的文件管理器中加密文件
  19. 谈谈奋斗里陆涛为什么不爱米莱
  20. (七)Python绘图基础:Matplotlib绘图

热门文章

  1. 转:在Linux服务器上配置phpMyAdmin
  2. CoreAnimation
  3. CSDN - 盛洪宇(技术胖) - Vue2.x从入门到实战
  4. js经验分享 JavaScript反调试技巧
  5. opencv3/C++ 将图片转换为视频
  6. PHP对接企业微信审批回调
  7. Tcp、select函数实现在线词典(C语言)
  8. 【Ubuntu】Ubuntu16.04安装GTX960M显卡驱动(960、1070and 750ti直接图形界面安装亲测能用,1080需要到命令界面安装亲测能用)
  9. 微信小程序 柱状图的使用
  10. win7 计算机名称 ip6,Win7系统提示ipv6无网络访问权限的两种原因及解决方法