DLL用于非C++语言时的注意事项

来源:互联网 发布:软件测试 北大青鸟 编辑:程序博客网 时间:2024/05/20 19:49

我做的一个示例程序

建立win32 dynamic link library project,

add dummy.h

#ifndef _DUMMY_H_
#define _DUMMY_H_


extern "C" _declspec(dllexport) int Mult(int);


#endif /* _DUMMY_H_ */

add dummy.cpp

// dummy.cpp : Defines the entry point for the DLL application.
//

#include "dummy.h"

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>


extern "C" _declspec(dllexport) int Mult (int a)
{
    return a*10;
}


BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}

这样就可以生成了dll。

然后建立一个win32 console project

add test.cpp

#include <stdio.h>
#include <stdlib.h>

//windows head file
#include <windows.h>
typedef int (*DLLFunc)(int );


int main()
{
    
    DLLFunc dllFunc;
    
    HINSTANCE hInstLibrary = LoadLibrary("dummy.dll");
    
    if (hInstLibrary == NULL)
        
    {
        
        FreeLibrary(hInstLibrary);
        
    }
    
    dllFunc = (DLLFunc)GetProcAddress(hInstLibrary, "Mult");
    
    if (dllFunc == NULL)
        
    {
        
        FreeLibrary(hInstLibrary);
        
    }
    else{
        int s=dllFunc(10);
        printf("%d\n",s);
        
        
        FreeLibrary(hInstLibrary);
        system("pause");
    }
    return 0;
}

run. OK!


转自 http://blog.tianya.cn/blogger/post_read.asp?BlogID=79455&PostID=16533531

VC DLL编译和DEF的关系(转载)


问题1:

  
  查看一个编写的dll的输出,函数名老是 _xxxx@n之类,已经使用了extern "C"并工程中添加了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程序来说,不是按名称进行调用,而是按照这个数进行调用的,所以最好给出。
  
  
  
  看来是def文件没起到作用。最终发现需要将def文件配置到VC工程中的“链接器”的“模块定义文件”中。
  
  
  
  问题2:
  
  在def中增加几个输出函数定义后(这些函数本来已经输出,但没有加到def文件中),发现某些以前编译的程序执行报错找不着函数,但其他一些程序没有报错。看来报错的程序连接时没有使用lib文件,而没报错的使用了;没使用lib文件的通过hint定位函数,所以总能找到但可能找错了——难怪听说这个库以前发生过函数调错的现象。
  
  增加了输出函数却忘了在def中增加定义,新手写的代码又无人检查,最严重的是后期的版本问题。
原创粉丝点击