DLL导出API注意事项

news2024/11/26 2:52:10

在这里插入图片描述

文章目录

  • 问题
  • 原则
  • 示例一
    • 解决方案
  • 示例二
    • 解决方法
  • 参考


问题

    在 windows 平台下,如果在动态库的接口中使用 std::string 或其它 std 容器,会导致崩溃或其它内存问题,所以一般要求动态库的接口必须是 C 语言实现。

原则

    一个原则:某个模块中分配的空间就应该由它来释放!比如说在 dll 中分配的空间就应由这个 dll 来释放,而不应该由 main 来释放,因为 dll 中用来分配空间的环境可能和 main 中用来分配的环境不一样。关于这一点 window核心编程 中的 dll 里面进行了讲解,但是说真的我还是不明白为什么会这样。但是要记住这个原则!

示例一

    main 中的如下语句:

	string str1("l10");
	string str2("l10value");
	pi->addElement(str1, str2 );
	//pi是指向 dll 提供的一个接口的指针。

    dll 中是如下实现 addElement 函数的:

bool Test::addElement(string elementName, string elementValue)
{
	// ... 省略
	return true;
	// 返回时对 elementName,elementValue 进行析构,这导致释放它们具体字符串的空间,
	// 但是这些字符串的空间是在 main 中分配的,所以出现运行时错误!!!(其实是无效内存访问)
}

解决方案

    对于上面这种情况我们只要把 dll 的改成引用就可以了:

bool Test::addElement(string &elementName, string &elementValue)
{
	// ... 省略
	return true;
}

    备注:感觉把 string 用于 dll 并不是一个好主意。

示例二

    前言:为什么要用浅拷贝。因为假如字符串空间很大的话,若不用浅拷贝则将非常费时且浪费空间。

  1. string 作为 dll 导出接口的方法的输入参数,这时可以作为引用来传递。这种情况下容易解决,如上。 这里是指 dll 中不会对 string 作任何改变。

  2. dll 导出接口的方法返回一个 string,也就是字符串空间在 dll 中分配,然后在 main 中获得这个 string, 则以为在 main 中释放空间,但由于是浅拷贝,所以将出现错误。

    dll 中的代码如下:

string Test::getString()
{
	string s("abc");
	return s;
}

    main 中的代码如下:

main()
{
	// 省略 ...
	string strretdll = pi->getString();
	return 0;
	// 返回时调用 string 的析构函数,进而释放字符串空间,但由于这个空间不是在 main 模块
	// 中分配的,这将导致错误。
}

    好问题出来了:在 getString 返回时为什么不会把字符串空间析构掉呢? 事实上 string 的析构函数要调用一个称为 _Tidy(bool) 的函数来处理。注意不同的 stl 实现如何析构 string 的具体方式是不一样的。总之经过我观察之后,在 getString 返回时并不释放字符串空间,尽管执行了析构函数。我想这一点有点像智能指针。

解决方法

    对于这种情况的解决方法:

  1. 把空间分配和释放均在 main 中,但是 main 并不知道要具体分配多少空间

  2. 把空间分配和释放均在 dll 中, 但是如何才能在 main 中调用 dll 的方法来要求 dll 释放空间。
    // 现在该想到 com 中 IUnknown 的重要作用了吧!!!!

  3. string 作为 dll 导出接口的方法的输出参数。这种情况同样出现情况 2 的问题。

  4. string 作为 dll 导出接口的方法的输入输出参数。具有输出特性时和情况 2 相似。

思考:能不能用指向 string 的指针呢?
   
不方便!!

    最后我下一个结论:在 dllstring 不能作为输出属性的参数!!

    所以,我们只能显式地在 dll 中定义一个输出函数,用这个输出函数来释放 dll 分配的空间!!

    不过也可以在 VC 工程中使用 PROGECT—>SETTINGS 中,选择 C/C++ CATEGORY 选择 code generationuser run-time lib 选择 debug multithreanded ,这样也可以避免 string 内存没有释放问题。建议一般不在动态链接库中返回 string

参考

DLL string
C++实现简单的string

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1565501.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW专栏二、调用子VI

该节目标是创建带子vi,修改vi属性,测试可重入和不可重入的区别 一 、设置子VI 把VI封装成为子VI,可以帮助模块化程序,简化代码结构。 任何VI本身都可以成为别的VI的子VI。 1.1、设置输入输出端子 1、在前面板空白处&#xff0…

JavaScript中什么叫深拷贝?

在 JavaScript 中,深拷贝指的是创建一个新的对象,这个新的对象与原始对象完全独立,没有任何共享的属性或者数据,它们不共享同一块内存地址。深拷贝会复制原始对象的所有属性和嵌套对象的所有属性,包括嵌套对象中的属性…

Mybatis——查询数据

查询操作 根据用户id查询单条记录,在映射器接口(UserMapper)中定义如下方法: package org.example.mapper;import org.example.demo.User;import java.util.List;public interface UserMapper {//根据id查询UserUser selectUserById(Integer userId); …

使用 RisingWave、NATS JetStream 和 Superset 进行实时物联网监控

在物联网(IoT)背景下,处理实时数据会遇到一些特定的障碍,如边缘计算资源不足、网络条件限制、扩展性存在问题、设备间有多样性差异。要克服这些挑战,需要高效的边缘计算技术、强大的安全措施、标准化协议、可扩展的管理…

【升降自如】OLED升降透明屏,智能调节,打造个性化观影体验

OLED升降透明屏,作为科技领域的创新之作,以其升降自如、智能调节的特点,为用户带来了前所未有的个性化观影体验。 这款透明屏采用先进的OLED显示技术,不仅色彩鲜艳、对比度高,而且具备出色的透明性能。更值得一提的是&…

3D人脸扫描技术与数字人深度定制服务:赋能打造超写实3D数字分身

在数字时代,3D数字分身有着广泛的应用场景,在动画视频、广告宣传片、大型活动主持人、AI交互数字人等领域,发挥着重要的商业价值。其中,3D人脸扫描技术,推动了超写实3D数字分身的诞生。 公司案例 2023海心沙元宇宙音乐…

10_MVC

文章目录 JSON常用的JSON解析Jackson的常规使用指定日期格式 MVC设计模式MVC介绍前后端分离案例(开发与Json相关接口) 三层架构三层架构介绍 JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,是存…

[中级]软考_软件设计_计算机组成与体系结构_06_ 流水线技术

流水线技术 前言相关考试考点一:流水线执行时间概念流水线步骤解析参数计算案例解析:流水线计算第一问第二问 考点二:流水线吞吐率 前言 第一章比较重要的一种计算题型,经常考到,一般考试1 ~ 2分。 相关考试 流水线…

【智能算法】蜜獾算法(HBA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2021年,FA Hashim等人受到自然界中蜜獾狩猎行为启发,提出了蜜獾算法((Honey Badger Algorithm,HBA)。 2.算法原理 2.1算法思想 蜜獾以其…

文献速递:深度学习胰腺癌诊断--深度学习算法用于从疾病轨迹预测胰腺癌风险

文献速递:深度学习胰腺癌诊断--深度学习算法用于从疾病轨迹预测胰腺癌风险 麦田医学 美好事物中转站 2024-04-02 14:36 Title 题目 A deep learning algorithm to predict risk of pancreatic cancer from disease trajectories 深度学习算法用于从疾病轨迹预测…

WPF-基础及进阶扩展合集(持续更新)

目录 一、基础 1、GridSplitter分割线 2、x:static访问资源文件 3、wpf触发器 4、添加xaml资源文件 5、Convert转换器 6、多路绑定与多路转换器 二、进阶扩展 1、HierarchicalDataTemplate 2、XmlDataProvider从外部文件获取源 3、TextBox在CellTemplate中的焦点问题…

【LeetCode热题100】79. 单词搜索(回溯)

一.题目要求 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平…

揭秘代码安全:告别硬编码,灵活策略守护你的账户密码信息安全

前言 在编写代码时,为了遵循严格的安全规范,应避免硬编码任何敏感信息如账号凭证、密钥等直接出现在源代码中。相反,推荐采取安全措施,如使用环境变量、加密存储或安全凭据管理系统来间接引用和保护这类数据。如此一来&#xff0c…

使用 Docker 部署 Puter 云桌面系统

1)Puter 介绍 :::info GitHub:https://github.com/HeyPuter/puter ::: Puter 是一个先进的开源桌面环境,运行在浏览器中,旨在具备丰富的功能、异常快速和高度可扩展性。它可以用于构建远程桌面环境,也可以作为云存储服…

c++对象指针

对象指针在使用之前必须先进行初始化。可以让它指向一个已定义的对象,也可以用new运算符动态建立堆对象。 定义对象指针的格式为: 类名 *对象指针 &对象; //或者 类名 *对象指针 new 类名(参数); 用对象指针访问对象数据成员的格式为&#xff1a…

python很坐标报错ufunc ‘isfinite‘ not supported for the input types

python使用plt画图的时候,出错。 出错全文如下: Traceback (most recent call last): plt.show() return _get_backend_mod().show(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ __call__ manager.show(**kwar…

Node.js环境调用百度智能云(百度云)api鉴权认证三步走

方式一 :Postman脚本的方式生成v1版本的认证字符串 Postman脚本下载 下载Postman pre-request Script 设置 Authorization 示例脚本 方式二:在线签名工具生成 (试用于验证编程字符串签名是否有错误) 签名计算工具 https://cloud.baidu.com/signature/index.html …

深入核心招聘场景,用友大易帮助健合集团解决「渠道、效率、体验」三件事

自1999年成立以来,健合集团一直致力于婴幼儿营养与护理、成人自然健康营养与护理、以及宠物营养与护理三大核心领域。作为全球高端家庭营养及护理品牌的佼佼者,健合集团始终秉持「让人们更健康更快乐」的企业理念,这不仅体现在产品和服务上&a…

腾讯云(CVM)托管进行权限维持

前言 刚好看到一个师傅分享了一个阿里云ECS实战攻防,然后想到了同样利用腾讯云CVM的托管亦可实现在实战攻防中的权限维持。 简介 腾讯云自动化助手(TencentCloud Automation Tools,TAT)是一个原生运维部署工具,它可…

苹果放弃造车计划,专家称之All in AI / 阿里巴巴主席蔡崇信:中国电子商务渗透率有望超过40% |魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件🔥,更新AIGC的最新动态,生成相应的魔法简报,节省阅读时间👻 🔥资讯预览 苹果放弃造车计划,专家称之All in AI 阿里巴巴主席蔡崇信&#…