zoukankan      html  css  js  c++  java
  • __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.

    大部分转载 小部分自写
  • 相关阅读:
    GhostBSD 3.0RC3,基于GNOME的FreeBSD
    Nagios 3.4.3 发布,企业级监控系统
    Jolokia 1.0.6 发布, JMX远程访问方法
    微软希望开发人员不要使 WebKit 成为新版 IE6
    Kwort Linux 3.5 正式版发布
    EJDB 1.0.24 发布,嵌入式 JSON 数据库引擎
    Pale Moon 15.3 Firefox“苍月”优化版发布
    Galera Load Balancer 0.8.1 发布
    SmartSVN V7.5 正式发布
    PostgresQL建立索引如何避免写数据锁定
  • 原文地址:https://www.cnblogs.com/8586/p/1266646.html
Copyright © 2011-2022 走看看