DLL导出API注意事项

简介: DLL导出API注意事项

问题

    在 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


目录
相关文章
|
10月前
|
API 对象存储
postman导出api文档
postman导出api文档
104 0
|
存储 Web App开发 编解码
漏刻有时API接口实战开发系列(3):萤石UIKit Javascript开发平台的注意事项
漏刻有时API接口实战开发系列(3):萤石UIKit Javascript开发平台的注意事项
142 0
|
13天前
|
缓存 监控 API
淘宝 API 接口使用的技术要点与注意事项
在数字化商业环境中,淘宝API为开发者提供了强大的工具,用于与淘宝平台交互,获取商品信息及处理交易等。本文总结了正确使用API的关键技术要点:注册认证、理解接口文档、遵守调用限制、确保参数准确性、保护数据安全、处理异常、性能优化、版本兼容、合规性及日志监控,帮助开发者实现高效、安全的程序开发。
|
3月前
|
存储 Java API
JavaSE——常用API(2/3)-String使用时的注意事项、String的应用案例
JavaSE——常用API(2/3)-String使用时的注意事项、String的应用案例
31 1
|
4月前
|
安全 API
OpenAI邮箱API发送邮件注意事项
使用OpenAI邮箱API需注意API密钥安全,避免泄露;确保邮件内容合法合规,不发送垃圾邮件;设置正确发件人信息,防止被视为垃圾邮件;确认收件人信息准确;控制发送频率;保持内容格式规范;记录发送日志;并先进行发送测试。遵循这些提示可确保邮件发送顺利。
|
4月前
|
API 开发工具 数据安全/隐私保护
API接口的对接流程和注意事项(淘宝商品详情店铺)
随着互联网技术的发展和应用的普及,API接口已经成为不同系统、不同应用之间进行交互和数据交换的重要方式。API接口使得不同的系统能够互相调用对方的功能,提高了系统的灵活性和扩展性。但是,在进行API接口对接的过程中,需要注意一些流程和事项,以确保对接的顺利进行和系统的稳定运行。
|
4月前
|
API 开发工具 数据安全/隐私保护
API接口的对接流程和注意事项
随着互联网技术的发展和应用的普及,API接口已经成为不同系统、不同应用之间进行交互和数据交换的重要方式。API接口使得不同的系统能够互相调用对方的功能,提高了系统的灵活性和扩展性。但是,在进行API接口对接的过程中,需要注意一些流程和事项,以确保对接的顺利进行和系统的稳定运行。
|
11月前
|
XML 存储 大数据
使用 SAP UI5 sap.ui.export.Spreadsheet API 进行 Excel 导出的一些限制
使用 SAP UI5 sap.ui.export.Spreadsheet API 进行 Excel 导出的一些限制
|
测试技术 程序员 API
API 接口的对接流程和注意事项
随着互联网技术的发展和数字化时代的到来,API接口已经成为应用程序之间进行数据交换和通信的重要方式。API即应用程序接口,是一种定义、调用和交互的规范,使得不同应用程序之间可以相互调用和共享资源。本文将从程序员的视角出发,详细介绍API接口的对接流程和注意事项。
|
XML 存储 JSON
常用的API接口对接方式和注意事项
常用的API对接方式和注意事项 随着互联网的发展,API(应用程序接口)已经成为了不可或缺的一部分。API允许不同的软件系统进行通信和数据交互,为开发者提供了一种简单、灵活和高效的方式来集成不同的软件系统