一个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下。
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下。
相关文章推荐
- 一个Win32 C++ 动态连接库的模板 --- 调用方可管理DLL分配的内存
- 一个Win32 C++ 动态连接库的模板 — 调用方可管理DLL分配的内存
- 程序员面试金典: 9.13 C和C++ 13.10用C编写一个my2DAlloc函数,可分配二维数组。将malloc函数的调用次数降到最少,并确保 可通过arr[i][j]访问该内存。
- C++/CLI C#调用dll速度比较和内存分配时间测试
- 智能指针模板,要管理动态分配的内存
- 一个Ip2long函数,通过调用go tool pprof分析,竟发现内存分配了3G
- (原创)VB调用DLL(VC)使用结构体参数时的内存对齐及分配的问题.
- 一个DLL,在exe调用正常,换到OCX调用就内存溢出
- 智能指针的模板,用来管理动态分配的内存
- .NET通过 P/Invoke调用win32 dll的一个实际例子
- 定义一个函数模板,为指定的数据类型分配内存。
- 编写一个函数,此函数使用动态存储分配来产生一个字符串的副本。例如函数为strclone,则调用p=strclone(str),将会为一个新的字符串分配和str占内存大小相同的一个字符串,并将字符串st
- Win32DLL编写与调用模板
- 如何在Dll中分配内存,而在调用程序里释放
- 用vs2008写了一个动态库,其中有申请内存,用vc6.0写了一个exe调用动态库,并释放dll申请的内存:dbgheap.c Line:1011
- pSOS&Win32--系统调用封装-任务管理(2): 开始 重起 挂起
- 在 C# 中通过 P/Invoke 调用Win32 DLL
- 如何让new操作符不分配内存,只调用构造函数
- 将w32 dll文件以资源的形式加载,并且在内存中调用
- C# 调用C++ DLL 尝试读取或写入受保护的内存