您的位置:首页 > 编程语言 > C语言/C++

一个Win32 C++ 动态连接库的模板 --- 调用方可管理DLL分配的内存

2007-04-04 18:47 465 查看
一个Win32 C++ 动态连接库的模板

cheungmine

一般情形下,使用C++编写动态库(DLL),在方法参数中不能输出STL对象类型, 如 std::string,这给我们的工作带来极大的麻烦。我参考一些资料,写了个C++ DLL模板,专门解决了这个问题。

使用VS2003新建一个Win32 DLL工程——DllCppTmpl,选择空项目,即什么也不自动创建。然后把下面2个文件加入到你的工程中,编译之。

文件1:DllCppTmpl.h

//
// DllCppTmpl.h - Win32 CPP Dll Template
// cheungmine
// under licence BSD
// 2007
//
#ifndef _DLLCPPTMPL_H_
#define _DLLCPPTMPL_H_

//
// DllExport
//
#ifdef DLLCPPTMPL_DLLEXPORT
#define DLLCPPTMPL_DLL __declspec(dllexport)
#elif defined(DLLCPPTMPL_IMPORTS)
#define DLLCPPTMPL_DLL __declspec(dllimport)
#else
#define DLLCPPTMPL_DLL
#endif

//
// 公共头文件
//
#include <string>
using namespace std;

#include <new> // for new_handler

#define DLLCPPTMPL_API __cdecl

typedef void * (DLLCPPTMPL_API * PtrNew)(size_t);
typedef void (DLLCPPTMPL_API * PtrDelete)(void *);
typedef void (DLLCPPTMPL_API * PtrGetNewAndDelete)(PtrNew &, PtrDelete &);
typedef new_handler (DLLCPPTMPL_API * PtrSetNewHandler)(new_handler);
typedef void (DLLCPPTMPL_API * PtrSetNewAndDelete)(PtrNew, PtrDelete, PtrSetNewHandler);

//
// DLLCPPTMPL_IMPORTS
//
#ifdef DLLCPPTMPL_IMPORTS
#ifdef _DLL
// cause CRT DLL to be initialized before Crypto++ so that we can use malloc and free during DllMain()
#ifdef NDEBUG
#pragma comment(lib, "msvcrt")
#else
#pragma comment(lib, "msvcrtd")
#endif
#endif

#if !(defined(_MSC_VER) && (_MSC_VER < 1300))
using std::new_handler;
#endif

// When DllCppTmpl attaches to a new process, it searches all modules loaded
// into the process space for exported functions "GetNewAndDeleteFor_DllCppTmpl"
// and "SetNewAndDeleteFrom_DllCppTmpl". If one of these functions is found,
// Crypto++ uses methods 1 or 2, respectively, by calling the function.
// Otherwise, method 3 is used.
static PtrNew _s_pNew = NULL;
static PtrDelete _s_pDelete = NULL;

extern "C" __declspec(dllexport) void __cdecl SetNewAndDeleteFrom_DllCppTmpl(PtrNew pNew, PtrDelete pDelete, PtrSetNewHandler pSetNewHandler)

void * __cdecl operator new (size_t size)

void __cdecl operator delete (void * p)
#endif // DLLCPPTMPL_IMPORTS

//
// DLL接口方法
//
namespace DllCppTmpl
#endif /* ndef _DLLCPPTMPL_H_ */

文件2:DllCppTmpl.cpp

#define DLLCPPTMPL_DLLEXPORT __declspec(dllexport)

#include "DllCppTmpl.h"

#include <string.h>

#include <iostream>
#include <time.h>
#include <windows.h>

#if (_MSC_VER >= 1000)
#include <crtdbg.h> // for the debug heap
#endif

// 如果使用动态库: DllCppTmpl
using namespace DllCppTmpl;

//
// DLL标准输出
//
#ifdef DLLCPPTMPL_EXPORTS
#if !(defined(_MSC_VER) && (_MSC_VER < 1300))
using std::new_handler;
using std::set_new_handler;
#endif

void _CallNewHandler()

static PtrNew _s_pNew = NULL;
static PtrDelete _s_pDelete = NULL;

static void * New (size_t size)

static void SetNewAndDeleteFunctionPointers()

void * operator new (size_t size)

void operator delete (void * p)

void * operator new [] (size_t size)

void operator delete [] (void * p)
#endif // #ifdef DLLCPPTMPL_EXPORTS

// Test
void DLLCPPTMPL_DLL DllCppTmpl::Test1(const char *in, char** out)

void DLLCPPTMPL_DLL DllCppTmpl::Test2(const string& in, string& out)

好了,开始写客户端。建一个Win32 console项目,如下:

// testDllCppTmpl.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <windows.h>

#define DLLCPPTMPL_IMPORTS // 必须定义在前

#include "../DllCppTmpl/DllCppTmpl.h"
#pragma comment(lib, "../DllCppTmpl/Debug/DllCppTmpl.lib")

using namespace DllCppTmpl;
int _tmain(int argc, _TCHAR* argv[])
...{


char in[] = "cheungmine";


char* out = 0;




DllCppTmpl::Test1(in, &out);




printf("Test1: %s ", out);


delete out;






string in2="cheungmine";


string out2;




DllCppTmpl::Test2(in2, out2);




printf("Test2: %s ", out2.c_str());






return 0;


}

注意路径的正确,和DllCppTmpl.dll要放到system32下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐