Common.h
#ifndef _COMMON_H_ #define _COMMON_H_ #ifdef DLL_EXPORT #define DLL_API extern "C" __declspec(dllexport) #define DLL_API_CLASS __declspec(dllexport) #else #define DLL_API extern "C" __declspec(dllimport) #define DLL_API_CLASS __declspec(dllimport) #endif DLL_API int Add(int a, int b); DLL_API int Sub(int a, int b); /* lib文件包含了DLL 导出函数的符号名及序号(并不含有实际的代码) dll文件 */ /* 因为C++导出或导入动态链接库会发生名字的改编,如果不想发生名字改编,使用如下代码: #define DLL_API extern "c" _declspec(dllexport) 如果函数使用标准调用约定_stdcall(默认使用了_cdecl), 即使使用了extern "c",此函数名仍会发生改编 */ /* 导出整个类 导出类只能通过静态调用方式使用 (注意dll地狱问题,详细请参考google) */ class DLL_API_CLASS CKPerson { public: CKPerson(void); ~CKPerson(void); int GetOld(void) const; const char* GetName(void) const; void SetOld(int nOld); void SetName(const char* szName); private: int m_nOld; char m_szName[64]; }; class DLL_API_CLASS/* 必须的,否则静态调用中编译失败 */ CKPerson1 { public: CKPerson1(void); ~CKPerson1(void); int GetOld(void) const; const char* GetName(void) const; void SetOld(int nOld); void SetName(const char* szName); private: int m_nOld; char m_szName[64]; }; DLL_API CKPerson1* CreateKPersonInstance(void); class DLL_API_CLASS CKPerson2 { public: CKPerson2(void); ~CKPerson2(void); int GetOld(void) const; const char* GetName(void) const; void SetOld(int nOld); void SetName(const char* szName); private: int m_nOld; char m_szName[64]; }; DLL_API CKPerson2* CreateKPerson2Instance(void); #endif
Common.cpp
#include "stdafx.h" #define DLL_EXPORT #include "Common.h" int Add(int a, int b) { return ( a + b); } int Sub(int a, int b) { return (a - b); } CKPerson::CKPerson(void) : m_nOld(0) { memset(m_szName, 0, 64); } CKPerson::~CKPerson(void) { } int CKPerson::GetOld(void) const { return m_nOld; } const char* CKPerson::GetName(void) const { return m_szName; } void CKPerson::SetOld(int nOld) { m_nOld = nOld; } void CKPerson::SetName(const char* szName) { strncpy(m_szName, szName, 64); } //-------------------------------------- CKPerson1::CKPerson1(void) : m_nOld(0) { memset(m_szName, 0, 64); } CKPerson1::~CKPerson1(void) { } int CKPerson1::GetOld(void) const { return m_nOld; } const char* CKPerson1::GetName(void) const { return m_szName; } void CKPerson1::SetOld(int nOld) { m_nOld = nOld; } void CKPerson1::SetName(const char* szName) { strncpy(m_szName, szName, 64); } CKPerson1* CreateKPersonInstance(void) { return new CKPerson1(); } //-------------------------------------- CKPerson2::CKPerson2(void) : m_nOld(0) { memset(m_szName, 0, 64); } CKPerson2::~CKPerson2(void) { } int CKPerson2::GetOld(void) const { return m_nOld; } const char* CKPerson2::GetName(void) const { return m_szName; } void CKPerson2::SetOld(int nOld) { m_nOld = nOld; } void CKPerson2::SetName(const char* szName) { strncpy(m_szName, szName, 64); } CKPerson2* CreateKPerson2Instance(void) { return new CKPerson2(); }
callDll.cpp
// callDll.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using namespace std; /* 静态调用方式 */ #include "../../myDll/myDll/Common.h" //使用标示符表示这两个函数是从动态链接库的.lib文件引用的,以生成效率更高的代码 //extern "C" extern int Add(int a, int b); //行的通 //extern "C" extern int Sub(int a, int b); #pragma comment(lib, "../debug/myDll.lib") int _tmain(int argc, _TCHAR* argv[]) { cout << Add(2, 3) << endl; cout << Sub(2, 3) << endl; CKPerson pp; pp.SetOld(100); pp.SetName("liyong"); cout << pp.GetOld() << endl; cout << pp.GetName() << endl; CKPerson1* pKPersion = CreateKPersonInstance(); if (NULL != pKPersion) { pKPersion->SetOld(101); pKPersion->SetName("liyongcc"); cout << pKPersion->GetOld() << endl; cout << pKPersion->GetName() << endl; delete pKPersion; pKPersion = NULL; } return 0; } /* 动态调用方式 */ /* class __declspec(dllimport) CKPerson2 { public: CKPerson2(void); ~CKPerson2(void); int GetOld(void) const; const char* GetName(void) const; void SetOld(int nOld); void SetName(const char* szName); private: int m_nOld; char m_szName[64]; }; int _tmain(int argc, _TCHAR* argv[]) { typedef int (*PFUN1)(int a, int b); typedef CKPerson2* (*PFUN2)(void); HMODULE hDll = ::LoadLibrary(_T("myDll.dll")); if (NULL != hDll) { PFUN1 pFun1 = (PFUN1)::GetProcAddress(hDll, "Add"); cout << (*pFun1)(11, 112) << endl; pFun1 = (PFUN1)::GetProcAddress(hDll, "Sub"); cout << (*pFun1)(11, 112) << endl; PFUN2 pFun2 = (PFUN2)::GetProcAddress(hDll, "CreateKPerson2Instance"); CKPerson2* pKPerson2 = (*pFun2)(); if (NULL != pKPerson2) { pKPerson2->SetOld(102); //error LNK2019: unresolved external symbol pKPerson2->SetName("liyongccdd"); //error LNK2019: unresolved external symbol cout << pKPerson2->GetOld() << endl; //error LNK2019: unresolved external symbol cout << pKPerson2->GetName() << endl; //error LNK2019: unresolved external symbol delete pKPerson2; pKPerson2 = NULL; } } return 0; } */