EXE导出函数及def文件格式说明

转自:http://bbs.pediy.com/showthread.php?t=56840


EXE导出函数三种不同的解决办法(原理可能是一样的,:)):

1)在导出函数声明之前加上__declspec(dllexport)。例:

__declspec(dllexport) int Add(int a, int b);
__declspec(dllexport) int Sub(int a, int b);
__declspec(dllexport) int Mul(int a, int b);
__declspec(dllexport) int Div(int a, int b);


2)在链接器参数中设置。例:
#pragma comment(linker, "/EXPORT:_Add,@1,NONAME")
#pragma comment(linker, "/EXPORT:_Sub,@2,NONAME")
#pragma comment(linker, "/EXPORT:_Mul,@3,NONAME")
#pragma comment(linker, "/EXPORT:_Div,@4,NONAME")


3)添加一个def文件,例:
EXPORTS
  Add       @1  NONAME
  Sub       @2  NONAME
  Mul       @3  NONAME
  Div       @4  NONAME



另需要在链接器命令行参数中指定def文件名:
/DEF:Callee.def
注意:在def文件中 不要有
LIBRARY [library][BASE=address]

这样的语句。

相比较而言,后两种方法可以设置更多的参数。


函数举例:

extern "C" 
{


  int Add(int a, int b)
  {
    return (a + b);
  }


  int Sub(int a, int b)
  {
    return (a - b);
  }


  int Mul(int a, int b)
  {
    return (a * b);
  }


  int Div(int a, int b)
  {
    if (b == 0)
      return 0;
    else
      return (a / b);
  }


}
编译时会自动生成相应的导出库(lib)文件,供调用者使用。


调用方法和普通的动态链接库调用一样。
调用者必须能够找到被调用者的位置,否则报错,被调用者是否运行不影响。


调用代码举例:
extern "C"
{
  int Add(int a, int b);
  int Sub(int a, int b);
  int Mul(int a, int b);
  int Div(int a, int b);
}


#pragma comment (lib, "Callee.lib")


void CCallerDlg::OnBnClickedCalculate()
{
  // TODO: Add your control notification handler code here
  UpdateData(TRUE);


  switch (((CComboBox *)GetDlgItem(IDC_COMBO_OPERATOR))->GetCurSel())
  {
  case ADD:
    {
      m_iResult = Add(m_iNum1, m_iNum2);
      break;
    }
  case SUB:
    {
      m_iResult = Sub(m_iNum1, m_iNum2);
      break;
    }
  ...
  ...

根据导出序号调用dll函数

GetProcAddress(hDll,MAKEINTRESOURCE(sequence_num));


另外的方式:《编程高手箴言》一书所述调用门

//------------------------------------------------------------------------------------------------------------------------

def文件说明传送门:

http://andylin02.iteye.com/blog/441300

你可能感兴趣的:(EXE导出函数及def文件格式说明)