#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 ();
};
答案 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,否则您将获得未解析的符号来编译您的应用程序。因为应用程序不知道实际的add
和remove
成员函数。
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