• __declspec(dllexport)与.def文件



    在VC++中,如果生成DLL可以不使用.def文件。只需要在VC++的函数定义前要加__declspec(dllexport)修饰就可以了。但是使用__declspec(dllexport)和使用.def文件是有区别的。如果DLL是提供给VC++用户使用的,只需要把编译DLL时产生的.lib提供给用户,它可以很轻松地调用你的DLL。但是如果DLL是供VB、PB、Delphi用户使用的,那么会产生一个小麻烦。因为VC++对于__declspec(dllexport)声明的函数会进行名称转换,如下面的函数:
        __declspec(dllexport) int __stdcall IsWinNT()
        会转换为IsWinNT@0,这样你在VB中必须这样声明:
        Declare Function IsWinNT Lib "my.dll" Alias "IsWinNT@0" () As Long
        @的后面的数由于参数类型不同而可能不同。这显然不太方便。所以如果要想避免这种转换,就要使用.def文件方式。
        EXPORTS后面的数可以不给,系统会自动分配一个数。对于VB、PB、Delphi用户,通常使用按名称进行调用的方式,这个数关系不大,但是对于使用.lib链接的VC程序来说,不是按名称进行调用,而是按照这个数进行调用的,所以最好给出。如:
    EXPORTS 
    test @1 

      vc的dll,delphi调用的方法:

    ////K9RtExpr.h
    extern "C" __DECDLL
    unsigned int _stdcall K9RtSysInterrupt(int nInterruptTag);

    extern "C" __DECDLL
    unsigned int _stdcall K9RtSysExprm(unsigned int nModuleTag,
               float fTimeout,  
               void * pTestPar, 
               void * pResultPar 
               );

    // K9RtExpr.cpp
    #include "K9RtExpr.h"
    #include "RtCtrl.h"
    extern "C" __DECDLL
    unsigned int _stdcall K9RtSysInterrupt(int nInterruptTag)
    {
     return CRelayTestControl::Instance()->InterruptTest(nInterruptTag);
    }
    extern "C" __DECDLL
    unsigned int _stdcall K9RtSysExprm(unsigned int nModuleTag,
               float fTimeout,   
               void * pTestPar, 
               void * pResultPar 
               )
    {
     return CRelayTestControl::Instance()->RelayTest(
          nModuleTag, fTimeout, pTestPar, pResultPar);
    }

    ///K9RtExpr.def
    LIBRARY      "K9RtExpr"
    DESCRIPTION  K9RtExpr Windows Dynamic Link Library'

    EXPORTS
    K9RtSysInterrupt
    K9RtSysExprm
        ; Explicit exports can go here


    //delphi   调用文件
    unit InterfaceFunc;

    interface

    uses
       UnitData,Types;
      
    function K9RtSysExprm(nModuleTag:integer  ;
                            uTimeout:integer;
                            pTestPar:Pointer;
                            pResultPar:Pointer) : Integer; stdcall;

    function K9RtSysInterrupt(nInterruptType:Integer) : Integer; stdcall;

    implementation
    const DLLPATH  = 'RtBsExpr.dll';
    function K9RtSysExprm; external DLLPATH  name  'ExperimentRelayTest';
    function K9RtSysInterrupt; external DLLPATH  name 'InterruptRelayTest';

    end.

    大部分转载 小部分自写
  • 相关阅读:
    java 多级图的最短路径
    在dos中编译java文件
    apollo客户端的长轮询机制的原理
    Apollo配置中心动态生效实现原理
    jmx_exporter+prometheus+grafana实现kafka metric监控
    XXL-JOB(1) 分布式任务系统选型和XXL-JOB介绍,这篇文章相当的经典呀
    grafana根据不同prometheus server统计数据
    XXL-JOB的使用教程
    普罗米修斯官方文档
    Prometheus标签的管理
  • 原文地址:https://www.cnblogs.com/8586/p/1266646.html
Copyright © 2020-2023  润新知