zoukankan      html  css  js  c++  java
  • 为什么用C++写库 但是导出接口时 却定义了C的接口(李大哥告诉我的,我还没有理解,先记着吧。为以后查询方便,哈哈)

    导出C接口 使其拥有使用范围最广的接口 和多方式支持。比如操作系统,用C++写,但是接口申明了#ifdef C plus plus,判断如果是C++代码 就导出C接口,windows 下微软的几乎所有接口都是这样导出的,linux也一样。举例说明,我们导出一个C++接口 接口函数如下:KERNEL_USER_API int UserLogin(LPCTSTR lpszUserName,LPCTSTR lpszPassword);   假设这是一个内核库 封装了所有方法   然后提供给界面程序调用的一个登陆接口   使用方式就如同MessageBox.Show的用法   我们在使用时 直接在C和C++中包含h文件和调用lib库  然后直接使用  比如int类型      这里是为了返回状态   比如 返回0表示登陆成功    1表示用户名不存在  2表示 密码错误  那么用法如下  if(UserLogin(_T("传递的用户名"),_T("传递的密码")==0)
    {
    //登陆成功
    }    这里主要说 一下 为啥操作系统导出C接口而不是C++接口   因为我们这里定义了KERNEL_USER_API int UserLogin(LPCTSTR lpszUserName,LPCTSTR lpszPassword);   C++的接口时有特殊符号的  比如这里的接口就是UserLogin  但是编译后的C++的接口大概是这样的AZ&Z@@UserLogin@@@&ZZ   接口会有修饰符  所以无法通过显示连接调用   只能通过包含h文件 和lib、文件的方式隐式链接   并且不能用于 delphi VB C# 等其他语言调用   因为你不确定他的接口符号  如果你定义了C++的接口  那么你要显示链接调用这个dll  那么你还必须用C的接口在封装一个dll去调用C++的接口DLL   而是用C的接口  UserLogin就是UserLogin  在C和C++中可以用LoadLibrary直接在需要的时候加载这个dll   然后GetAddress  取得UserLogin的地址  函数地址  在其他任何语言中都可以用类似的方式加载并调用这个dll  比如C#中使用DllImport  来调用C接口的DLL  但是却不能用这个方法调用 C++接口的dll函数。但是C++ C 汇编是可以混编的 一个DLL中可以导出C和C++两种接口   比如操作系统 为啥都要申明C++模板使用C接口的原因

    如果这个软件是做平台  可能强调这个规范  如果只是实现功能 那么他们就不会强调接口规范  做平台 分三种客户 做功能只有一种客户   平台必须是走架构  从一开始就有一个大的方向和定位   一切都是按照最初的蓝图循序渐进的开发  有一个完整的体系结构  然后后期在这个结构上添砖加瓦  这就是架构  而且接口一般来说都是持久的  比如windows的api  从2000年到现在14年  基本上windows接口都是在NT建模时就定义好了对外接口  因为如果你的接口变了  那么一个程序使用了旧接口 到了新系统上接口变了   那么这个程序就会异常 甚至崩溃   以实现功能为目的的  多数走迭代  迭代的意思是    今天有一个需求A   那就实现需求A    明天有需求B 就实现B   没有统一的规划    属于走一步做一步     做不下去的时候重构   这种项目不需要规范接口     迭代产品是这样的     迭代产品只面向一个用户层     这个用户层就是使用者     不管是什么样的使用者    他们都只是使用这个东西     并不会基于这个东西再去实现更高级的东西     平台走架构    有三层用户          第一层是开发者    开发者可能需要借助这个平台开发一些         他们自己想要的功能        使用这个平台简化他们的部分工作    这是上游客户     中游客户      可能是借助这个平台提供线性服务的企事业单位           比如企业 学校 政府        下游客户就是最终的用户     迭代的产品      一直在纠结功能   每个功能的改善    基本上等于对整个程序都重构了一次    基于架构的   一个内核   所有的功能只是一个插件或者宿主服务     简略的说你可以理解为功能和框架以及适配器之间都是独立的     功能的更改只是更改功能    需要这个功能    我在这个框架上注册这个功能   让应用程序框架加载这个功能    不需要我就卸载掉你    功能的更改大大简化    (用VC2005建立一个工程 然后用2010建立一个同样类型的工程,然后去对比他们的配置和依赖项  一比之下,解决升级问题。)VS提供了F12   可以直接查看到函数原型    看到函数原型 对于函数返回值 参数类型 一目了然    举个最简单的例子:就拿MFC下的Create这个函数来说   这是一个无处不在的函数   Dialog中有这个函数       CMenuBar中也有    CToolbar中也有     CListctrl中也有   举例说明    dialog->Create和CMenubar->Create     函数原型的参数就不同    类型 貌似也不同   dialog是int、类型    CMenubar是BOOL类型   虽然可以互换   但是BOOL返回值仅包含0和1    而int返回值则是-65535到65535之间     然后写代码的人在这个Create中就纠结了   比如我们举个例子写 就用CDialog为例子   我们假设我们这个CDialog的类名为 CTestDlg    那么代码如下    CTestDlg dlg;//对话框对象申明
    dlg.Create(CTestDlg::IDD,GetDesktopWindow());    
    但是好多人 写到这里不会写了    然后去百度了  结果搜到了CMEnu的toolbar的 Create   函数参数是不同的   结果他们总是得不到正确答案    事实上他们只需要把光标移动到Create这个函数上   然后按下F12   就可以定位到原型   你的基类是CDialog就定位到Cdialog的Create原型

  • 相关阅读:
    Delphi下遍历文件夹下所有文件的递归算法
    mysql + unidac 使用事务例子
    新建DataSnap REST Application
    ClientDataSet中的错误处理
    TSQLConnection的事务处理
    ClientDataSet的查找和过滤功能
    TField中的GetText和SetText
    ClientDataSet中撤消与恢复操作及执行细节
    ClientDataSet中动态添加计算字段并用计算字段显示记录的UpdateStatus
    ClientDataSet中动态添加计算字段
  • 原文地址:https://www.cnblogs.com/fanshaomin/p/3778576.html
Copyright © 2011-2022 走看看