c/c++编写dll供其他语言调用

发布时间:2022-07-04 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了c/c++编写dll供其他语言调用脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

范例

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

比如F1a;https://github.COM/chinaran/Compute-file-or-string-md5

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

Dev c++

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

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

c/c++编写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)
#endif

DLLIMPORT void HelloWorld();

#endif

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

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

将这三个文件中的内容稍微整合一下到dll.h、dll.c和dllmain.c中,后面给出下载链接

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

c/c++编写dll供其他语言调用

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

import ctypes


dll = 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()))

运行一下成功得到结果:

c/c++编写dll供其他语言调用

另外需要注意的是,如果在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:Anacondaenvspy32libctypes__init__.py", line 369, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [@R_279_2406@rror 193] %1 不是有效的 Win32 应用程序。

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

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

vs2017

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

左上角文件->新建项目

c/c++编写dll供其他语言调用

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

c/c++编写dll供其他语言调用

代码基本上一样,复制到vs里就行了。就是不知道为什么他一定要pch.h这个头文件,改了名就报错

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

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

c/c++编写dll供其他语言调用

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

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

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

aardio调用dll

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

import console;
 
VAR dll = raw.loadDll("D:AndroidDll3DebugDLL3.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,即’’,正好是需要的长度。

脚本宝典总结

以上是脚本宝典为你收集整理的c/c++编写dll供其他语言调用全部内容,希望文章能够帮你解决c/c++编写dll供其他语言调用所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。