我正在导出DLL,但GetProcAddress返回127错误,如何解决?

时间:2010-06-23 07:05:44

标签: dllexport

#include "Calc.h"
#include<iostream>
#include <windows.h>
#include <WINERROR.H.>

typedef void (WINAPI * PCTOR) ();
int main()
{
    HMODULE hMod = LoadLibrary (L"Calci.dll");
    if (NULL == hMod)
    {
        printf ("LoadLibrary failed\n");
        return 1;
    }
    CCalc *pCCalc = (CCalc *) malloc (sizeof (CCalc));
    if (NULL == pCCalc)
    {
        printf ("memory allocation failed\n");
        return 1;
    }
    PCTOR pCtor = (PCTOR) GetProcAddress (hMod, "CCalc");//127 error
    int err = GetLastError();
    if (NULL == pCtor)
    {
        printf ("GetProcAddress failed\n");
        return 1;
    }
    __asm { MOV ECX, pCCalc };
    pCtor ();
    return 0;
}

//dll file
#include <tchar.h>


#ifdef CALC_EXPORTS
#define CALC_API __declspec (dllexport)
#else
#define CALC_API __declspec (dllimport)
#endif

#define SOME_INSTN_BUF        260

class CALC_API CCalc
{
private:
char m_szLastUsedFunc[SOME_INSTN_BUF];

public:
    CCalc (); 

    int Add (int i, int j);
    int Sub (int i, int j);
    TCHAR* GetLastUsedFunc ();

};

3 个答案:

答案 0 :(得分:0)

使用dumpbin.exe检查DLL中导出的确切名称。也许根本不存在?

如果您有机会使用导入库而不是LoadLibrary API,那就更好了。

答案 1 :(得分:0)

您正在调用GetProcAddress (hMod, "CCalc"),但"CCalc"不是函数的名称:它是类的名称。

您正在尝试加载CCalc::CCalc默认构造函数的地址:为此,请使用工具(例如dumpbin)来发现构造函数的“已修饰”名称。

然而,不是尝试动态加载和调用构造函数,实现此功能的更常用方法是在DLL中创建静态工厂方法,例如:像这样:

class CALC_API CCalc 
{ 
public:
    static CCalc* create() { return new CCalc(); }

private:
    //doesn't need to be public because users instantiate this class using 
    //the static create method
    CCalc();  

public:
    virtual int Add (int i, int j); 
    virtual int Sub (int i, int j); 
    virtual TCHAR* GetLastUsedFunc ();

    virtual ~CCalc() {}
};

然后使用GetProcAddress获取静态CCalc :: create函数的地址,因为它是静态的,你可以在不使用程序集来调用ECX的情况下调用它。

答案 2 :(得分:0)

您不能对类使用GetProcAddress。这不起作用。只有您可以解析其名称的函数才是未命中的“C”函数。

例如:

extern "C" __declspec(dllexport) CCalc *create_calc()
{
     return new CCalc;
}

现在,您可以使用。

解决它
GetProcAddress(halnder,"create_calc");

由于create_calc没有被破坏的功能。

此外,您必须提供抽象的API类而不实现,并使CCalc继承ACalc,否则您将获得未解析的符号来编译您的应用程序。因为应用程序不知道实际的addremove成员函数。

class ACalc {
public:
      virtual add(int i,int j) = 0;
      ...
      virtaul ~ACalc() {}
};

class CCalc : public ACalc {
public:
      virtual add(int i,int j) { ... };
      ...
};

在主程序中

ACalc *ptr= call_for_dll_function