delphi调用一个驱动程序里面的.dll文件,提示程序无法定位到‘函数’于该.dll文件上。头文件里面是怎样申明的:
#include <windows.h>
#include <winioctl.h>
extern "C" {
                __declspec(dllexport) HANDLE _stdcall   ADT800_DevLoad();
           }请教高手!谢谢了。

解决方案 »

  1.   

    你Delphi怎么声明的用dumpbin看看有没有导出这个函数,导出符号是什么
      

  2.   

    查看导出文件,导出符号为:_ADT800_DevLoad@0
      

  3.   

    在DELPHI中也是这么声明的么? __declspec
      

  4.   

    http://www.99inf.net/SoftwareDev/Delphi/54834.htm
    参考一下这片文章吧 
      

  5.   

     C++的参数调用方式           对应的DELPHI的参数调用方式
               _declspec                              cdecl
               WINAPI,CALLBACK                        stdcall
               PASCAL                                 pascal
    我遇到过你同样的问题,后来把STDCALL改为cdecl,问题就解决了,因为我在C++导出函数时使用的是“_declspec(dllexport)”,也就是C参数调用格式。
      

  6.   

    #include <windows.h> 
    #include <winioctl.h> 
    extern "C" { 
                    __declspec(dllexport) HANDLE _stdcall  ADT800_DevLoad(); 
              } 
    pascal:
    function ADT800_DevLoad:Handle ;cdecl ;你上面的提示跟压栈方式没有关系,你要检查下这个函数的有没有存在于这个DLL
      

  7.   

    用eXeScope查看后的结果:
    导出, ADT800.dll
    序列 地址 名字
    00000001 10001410 _ADT800_ADConfig@24
    00000002 10001520 _ADT800_ADFIFOReset@4
    00000003 10001170 _ADT800_ADSettings@12
    00000004 10001590 _ADT800_ChannelSwitch@4
    00000005 10001610 _ADT800_ClearIRQ@4
    00000006 100016C0 _ADT800_ClockDivisor@12
    00000007 10001690 _ADT800_ClockMode@12
    00000008 10001710 _ADT800_ClockReadBack@8
    00000009 10001870 _ADT800_ConfigIOPorts@16
    0000000A 100015F0 _ADT800_ConversionDone@4
    0000000B 10001570 _ADT800_DAStatus@4
    0000000C 10001050 _ADT800_DevClose@4
    0000000D 10001010 _ADT800_DevLoad@0
    0000000E 10001220 _ADT800_DigitToAnalog@12
    0000000F 10001370 _ADT800_DisableIRQ@4
    00000010 10001330 _ADT800_EnableIRQ@4
    00000011 100015B0 _ADT800_IRQStatus@4
    00000012 10001120 _ADT800_InitBoard@12
    00000013 10001540 _ADT800_ReadADFIFOFlag@4
    00000014 10001280 _ADT800_ReadData@4
    00000015 10001810 _ADT800_ReadDigitIO@8
    00000016 100017A0 _ADT800_ReadPITStatus@8
    00000017 100013A0 _ADT800_SelIRQSource@8
    00000018 100012D0 _ADT800_SetChannel@12
    00000019 100010D0 _ADT800_SetEvent@8
    0000001A 100015D0 _ADT800_StartConversion@4
    0000001B 10001630 _ADT800_WriteDataDA@12
    0000001C 10001840 _ADT800_WriteDigitIO@12
    0000001D 10001070 _ReadIOPort@8
    0000001E 10001060 _WriteIOPort@12引用的头文件 ADT800.h
    // ADT800 - include file for ADT800#include <windows.h>
    #include <winioctl.h>
    extern "C" {
                    __declspec(dllexport) HANDLE _stdcall   ADT800_DevLoad();
    __declspec(dllexport) void _stdcall   ADT800_InitBoard(HANDLE hDevice,unsigned int BaseAddr,int irq_chn);
      __declspec(dllexport) BOOL _stdcall      ADT800_DevClose(HANDLE hDevice);
      __declspec(dllexport) int _stdcall ADT800_SetEvent(HANDLE hDevice,HANDLE hEvent);
      __declspec(dllexport) unsigned int _stdcall ReadIOPort(HANDLE hDevice,unsigned int addr);
    __declspec(dllexport) void _stdcall WriteIOPort(HANDLE hDevice,unsigned int addr,unsigned int data);
    __declspec(dllexport) void _stdcall _stdcall ADT800_ADSettings(HANDLE hDevice,int Range, char Polarity);
    __declspec(dllexport) float _stdcall ADT800_DigitToAnalog(HANDLE hDevice,int DigitalValue,int *Curchannel);
    __declspec(dllexport) void _stdcall ADT800_ClearIRQ(HANDLE hDevice);
    __declspec(dllexport) void _stdcall ADT800_SetChannel(HANDLE hDevice,unsigned int ChannelL, unsigned int ChannelH);
    __declspec(dllexport) void _stdcall ADT800_StartConversion(HANDLE hDevice);
    __declspec(dllexport) char _stdcall ADT800_ConversionDone(HANDLE hDevice);
    __declspec(dllexport) void _stdcall ADT800_EnableIRQ(HANDLE hDevice);
    __declspec(dllexport) void _stdcall ADT800_DisableIRQ(HANDLE hDevice);
    __declspec(dllexport) void _stdcall ADT800_SelIRQSource(HANDLE hDevice,unsigned char IrqSou);
    __declspec(dllexport) void _stdcall ADT800_ADConfig(HANDLE hDevice,unsigned char Timer2Con,unsigned char DMACon,
                               unsigned char ADTrig,unsigned char GainCon,unsigned char FIFOEn);
    __declspec(dllexport) void _stdcall ADT800_WriteDataDA(HANDLE hDevice,unsigned int DAChannel, int DigitalValue);
    __declspec(dllexport) unsigned char _stdcall ADT800_DAStatus(HANDLE hDevice);
                    __declspec(dllexport) unsigned char _stdcall ADT800_ChannelSwitch(HANDLE hDevice);
                    __declspec(dllexport) unsigned char _stdcall ADT800_IRQStatus(HANDLE hDevice);
    __declspec(dllexport)  int _stdcall ADT800_ReadData(HANDLE hDevice);
    __declspec(dllexport) void _stdcall ADT800_ClockMode(HANDLE hDevice,unsigned char Clock, unsigned char Mode);
    __declspec(dllexport) void _stdcall ADT800_ClockDivisor(HANDLE hDevice,unsigned char Clock, unsigned int Divisor);
    __declspec(dllexport) unsigned int _stdcall  ADT800_ClockReadBack(HANDLE hDevice,unsigned char Timer);
    __declspec(dllexport) char _stdcall ADT800_ReadPITStatus(HANDLE hDevice,unsigned char Timer);
    __declspec(dllexport) unsigned char _stdcall ADT800_ReadDigitIO(HANDLE hDevice,unsigned char InputPort);
    __declspec(dllexport) void _stdcall ADT800_WriteDigitIO(HANDLE hDevice,unsigned char OutputPort, unsigned char v);
    __declspec(dllexport) void _stdcall ADT800_ConfigIOPorts(HANDLE hDevice,unsigned char Port0, unsigned char Port1,unsigned char Port2);
                    __declspec(dllexport) void _stdcall ADT800_ADFIFOReset(HANDLE hDevice);
                    __declspec(dllexport) unsigned char _stdcall ADT800_ReadADFIFOFlag(HANDLE hDevice);
    }此外还有:ADT800.sys,ADT800.lib,WinIo.dll,WinIo.sys。
    这是一个采集卡的驱动程序。
    如果哪位高手愿意,我可以把驱动发过去。
      

  8.   

    貌似你的extern "C" {
                    xxx
              } 
    根本没起作用。上面贴的是完整的 h 吗? 一般好像都会#ifdef CPP
    extern "C"
    {
    xxxxx
    }
    #endif你看看你是不似乎没有加编译条件。
      

  9.   

    用Dependency Walker或者PE Explorer就可以查看到处函数名
      

  10.   

    我是想用delphi调,我贴的是完整的.h文件内容。我也用PE Explore查看了。函数名就是每个导出函数都是_ADT800_DevLoad@0类似的。如果我要在delphi中调,用什么函数名呢?
      

  11.   

    LIBRARY     ADT800.DLLEXPORTS
        ADT800_ADConfig               = _ADT800_ADConfig@24                 
        ADT800_ADFIFOReset            = _ADT800_ADFIFOReset@4               
        ADT800_ADSettings             = _ADT800_ADSettings@12               
        ADT800_ChannelSwitch          = _ADT800_ChannelSwitch@4             
        ADT800_ClearIRQ               = _ADT800_ClearIRQ@4                  
        ADT800_ClockDivisor           = _ADT800_ClockDivisor@12             
        ADT800_ClockMode              = _ADT800_ClockMode@12                
        ADT800_ClockReadBack          = _ADT800_ClockReadBack@8             
        ADT800_ConfigIOPorts          = _ADT800_ConfigIOPorts@16            
        ADT800_ConversionDone         = _ADT800_ConversionDone@4            
        ADT800_DAStatus               = _ADT800_DAStatus@4                  
        ADT800_DevClose               = _ADT800_DevClose@4                  
        ADT800_DevLoad                = _ADT800_DevLoad@0                   
        ADT800_DigitToAnalog          = _ADT800_DigitToAnalog@12            
        ADT800_DisableIRQ             = _ADT800_DisableIRQ@4                
        ADT800_EnableIRQ              = _ADT800_EnableIRQ@4                 
        ADT800_IRQStatus              = _ADT800_IRQStatus@4                 
        ADT800_InitBoard              = _ADT800_InitBoard@12                
        ADT800_ReadADFIFOFlag         = _ADT800_ReadADFIFOFlag@4            
        ADT800_ReadData               = _ADT800_ReadData@4                  
        ADT800_ReadDigitIO            = _ADT800_ReadDigitIO@8               
        ADT800_ReadPITStatus          = _ADT800_ReadPITStatus@8             
        ADT800_SelIRQSource           = _ADT800_SelIRQSource@8              
        ADT800_SetChannel             = _ADT800_SetChannel@12               
        ADT800_SetEvent               = _ADT800_SetEvent@8                  
        ADT800_StartConversion        = _ADT800_StartConversion@4           
        ADT800_WriteDataDA            = _ADT800_WriteDataDA@12              
        ADT800_WriteDigitIO           = _ADT800_WriteDigitIO@12             
        ReadIOPort                    = _ReadIOPort@8                       
        WriteIOPort                   = _WriteIOPort@12                     
    在delphi下如何调用?
      

  12.   

    Delphi好象不支持@符号为函数名,所以不能直接写,理论上来讲,可以通过动态加载,并以cdecl来声明来达到目的。
      

  13.   

    dll里面的函数如.h文件里面定义的一样,@后面是参数的所占用memory的大小
    HANDLE _stdcall  ADT800_DevLoad() (ADT800_DevLoad@0)  no param
    void _stdcall  ADT800_InitBoard(HANDLE hDevice,unsigned int BaseAddr,int irq_chn); 
    (_ADT800_InitBoard@12)
    function ADT800_DevLoad: THandle;stdcall;
    procedure ADT800_InitBoard(hDevice: THandle;BaseAddr: Cardinal;irq_chn: Integer);stdcall;
    ....