一个申请物理内存数的程序,想编成dll文件供Delphi使用
程序如下:
#define _WIN32_WINNT 0x0502
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
BOOL bResult; // generic Boolean value
ULONG_PTR NumberOfPages; // number of pages to request
ULONG_PTR NumberOfPagesInitial; // initial number of pages requested
ULONG_PTR *aPFNs; // page info; holds opaque data
PVOID lpMemReserved; // AWE window
SYSTEM_INFO sSysInfo; // useful system information
int PFNArraySize; // memory to request for PFN arrayBOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
BOOL bEnable);extern "C" _declspec(dllexport) void AllocateMemory(ULONG_PTR AllocateQuantity)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( )); ULONG_PTR MEMORY_REQUESTED=AllocateQuantity;
GetSystemInfo(&sSysInfo); // fill the system information structure printf ("This computer has a page size of %d.\n", sSysInfo.dwPageSize); // Calculate the number of pages of memory to request. NumberOfPages = MEMORY_REQUESTED/sSysInfo.dwPageSize;
printf ("Requesting %d pages of memory.\n", NumberOfPages); // Calculate the size of the user PFN array. PFNArraySize = NumberOfPages * sizeof (ULONG_PTR); printf ("Requesting a PFN array of %d bytes.\n", PFNArraySize); aPFNs = (ULONG_PTR *) HeapAlloc (GetProcessHeap (), 0, PFNArraySize); if (aPFNs == NULL) {
printf ("Failed to allocate on heap.\n");
return;
} // Enable the privilege. if( ! LoggedSetLockPagesPrivilege( GetCurrentProcess(), TRUE ) ) {
return;
} // Allocate the physical memory. NumberOfPagesInitial = NumberOfPages;
bResult = AllocateUserPhysicalPages( GetCurrentProcess(),
&NumberOfPages,
aPFNs );
if( bResult != TRUE )
{
printf("Cannot allocate physical pages, error %u.\n", GetLastError() );
return;
} if( NumberOfPagesInitial != NumberOfPages )
{
printf("Allocated only %p pages.\n", NumberOfPages );
return;
} // Reserve the virtual memory.
lpMemReserved = VirtualAlloc( NULL,
MEMORY_REQUESTED,
MEM_RESERVE | MEM_PHYSICAL,
PAGE_READWRITE ); if( lpMemReserved == NULL )
{
printf("Cannot reserve memory.\n");
return;
} // Map the physical memory into the window.
bResult = MapUserPhysicalPages( lpMemReserved,
NumberOfPages,
aPFNs ); if( bResult != TRUE )
{
printf("MapUserPhysicalPages failed to map, error %u.\n", GetLastError() );
return;
} // unmap
bResult = MapUserPhysicalPages( lpMemReserved,NumberOfPages,NULL ); if( bResult != TRUE )
{
printf("MapUserPhysicalPages failed to unmap, error %u.\n", GetLastError() );
return;
}
return;}extern "C" _declspec(dllexport) void FreeMemory()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
// Free the physical pages. bResult = FreeUserPhysicalPages( GetCurrentProcess(),
&NumberOfPages,
aPFNs ); if( bResult != TRUE )
{
printf("Cannot free physical pages, error %u.\n", GetLastError() );
return;
} // Free virtual memory. bResult = VirtualFree( lpMemReserved,
0,
MEM_RELEASE );
return;
}/*****************************************************************
LoggedSetLockPagesPrivilege: a function to obtain, if possible, or
release the privilege of locking physical pages. Inputs: HANDLE hProcess: Handle for the process for which the
privilege is needed BOOL bEnable: Enable (TRUE) or disable? Return value: TRUE indicates success, FALSE failure.*****************************************************************/
BOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
BOOL bEnable)
{
struct {
DWORD Count;
LUID_AND_ATTRIBUTES Privilege [1];
} Info; HANDLE Token;
BOOL Result; // Open the token. Result = OpenProcessToken ( hProcess,
TOKEN_ADJUST_PRIVILEGES,
& Token); if( Result != TRUE ) {
printf( "Cannot open process token.\n" );
return FALSE;
} // Enable or disable? Info.Count = 1;
if( bEnable )
{
Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
}
else
{
Info.Privilege[0].Attributes = 0;
} // Get the LUID. Result = LookupPrivilegeValue ( NULL,
SE_LOCK_MEMORY_NAME,
&(Info.Privilege[0].Luid)); if( Result != TRUE )
{
printf( "Cannot get privilege value for %s.\n", SE_LOCK_MEMORY_NAME );
return FALSE;
} // Adjust the privilege. Result = AdjustTokenPrivileges ( Token, FALSE,
(PTOKEN_PRIVILEGES) &Info,
NULL, NULL, NULL); // Check the result. if( Result != TRUE )
{
printf ("Cannot adjust token privileges, error %u.\n", GetLastError() );
return FALSE;
}
else
{
if( GetLastError() != ERROR_SUCCESS )
{
printf ("Cannot enable SE_LOCK_MEMORY privilege, please check the local policy.\n");
return FALSE;
}
} CloseHandle( Token ); return TRUE;
}编译时候提示:
error C3861: “AllocateUserPhysicalPages”: 即使使用参数相关的查找,也未找到标识符
error C3861: “MapUserPhysicalPages”: 即使使用参数相关的查找,也未找到标识符
error C3861: “FreeUserPhysicalPages”: 即使使用参数相关的查找,也未找到标识符我在#pragma comment(lib, "advapi32.lib")下面加了下面几句:extern "C"_declspec(dllimport) BOOL AllocateUserPhysicalPages(
HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);extern "C"_declspec(dllimport) BOOL MapUserPhysicalPages(
PVOID lpAddress,ULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);extern "C"_declspec(dllimport) BOOL FreeUserPhysicalPages(
HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);
编译通过了,可是出现链接错误:
Dll_Memory_Control error LNK2019: 无法解析的外部符号 __imp__MapUserPhysicalPages ,该符号在函数 _Allocate_Memory 中被引用
Dll_Memory_Control error LNK2019: 无法解析的外部符号 __imp__AllocateUserPhysicalPages ,该符号在函数 _Allocate_Memory 中被引用
Dll_Memory_Control error LNK2019: 无法解析的外部符号 __imp__FreeUserPhysicalPages ,该符号在函数 _Free_Memory 中被引用第一次编dll文件,查了一些资料,还是找不到解决方法
程序如下:
#define _WIN32_WINNT 0x0502
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
BOOL bResult; // generic Boolean value
ULONG_PTR NumberOfPages; // number of pages to request
ULONG_PTR NumberOfPagesInitial; // initial number of pages requested
ULONG_PTR *aPFNs; // page info; holds opaque data
PVOID lpMemReserved; // AWE window
SYSTEM_INFO sSysInfo; // useful system information
int PFNArraySize; // memory to request for PFN arrayBOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
BOOL bEnable);extern "C" _declspec(dllexport) void AllocateMemory(ULONG_PTR AllocateQuantity)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( )); ULONG_PTR MEMORY_REQUESTED=AllocateQuantity;
GetSystemInfo(&sSysInfo); // fill the system information structure printf ("This computer has a page size of %d.\n", sSysInfo.dwPageSize); // Calculate the number of pages of memory to request. NumberOfPages = MEMORY_REQUESTED/sSysInfo.dwPageSize;
printf ("Requesting %d pages of memory.\n", NumberOfPages); // Calculate the size of the user PFN array. PFNArraySize = NumberOfPages * sizeof (ULONG_PTR); printf ("Requesting a PFN array of %d bytes.\n", PFNArraySize); aPFNs = (ULONG_PTR *) HeapAlloc (GetProcessHeap (), 0, PFNArraySize); if (aPFNs == NULL) {
printf ("Failed to allocate on heap.\n");
return;
} // Enable the privilege. if( ! LoggedSetLockPagesPrivilege( GetCurrentProcess(), TRUE ) ) {
return;
} // Allocate the physical memory. NumberOfPagesInitial = NumberOfPages;
bResult = AllocateUserPhysicalPages( GetCurrentProcess(),
&NumberOfPages,
aPFNs );
if( bResult != TRUE )
{
printf("Cannot allocate physical pages, error %u.\n", GetLastError() );
return;
} if( NumberOfPagesInitial != NumberOfPages )
{
printf("Allocated only %p pages.\n", NumberOfPages );
return;
} // Reserve the virtual memory.
lpMemReserved = VirtualAlloc( NULL,
MEMORY_REQUESTED,
MEM_RESERVE | MEM_PHYSICAL,
PAGE_READWRITE ); if( lpMemReserved == NULL )
{
printf("Cannot reserve memory.\n");
return;
} // Map the physical memory into the window.
bResult = MapUserPhysicalPages( lpMemReserved,
NumberOfPages,
aPFNs ); if( bResult != TRUE )
{
printf("MapUserPhysicalPages failed to map, error %u.\n", GetLastError() );
return;
} // unmap
bResult = MapUserPhysicalPages( lpMemReserved,NumberOfPages,NULL ); if( bResult != TRUE )
{
printf("MapUserPhysicalPages failed to unmap, error %u.\n", GetLastError() );
return;
}
return;}extern "C" _declspec(dllexport) void FreeMemory()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
// Free the physical pages. bResult = FreeUserPhysicalPages( GetCurrentProcess(),
&NumberOfPages,
aPFNs ); if( bResult != TRUE )
{
printf("Cannot free physical pages, error %u.\n", GetLastError() );
return;
} // Free virtual memory. bResult = VirtualFree( lpMemReserved,
0,
MEM_RELEASE );
return;
}/*****************************************************************
LoggedSetLockPagesPrivilege: a function to obtain, if possible, or
release the privilege of locking physical pages. Inputs: HANDLE hProcess: Handle for the process for which the
privilege is needed BOOL bEnable: Enable (TRUE) or disable? Return value: TRUE indicates success, FALSE failure.*****************************************************************/
BOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
BOOL bEnable)
{
struct {
DWORD Count;
LUID_AND_ATTRIBUTES Privilege [1];
} Info; HANDLE Token;
BOOL Result; // Open the token. Result = OpenProcessToken ( hProcess,
TOKEN_ADJUST_PRIVILEGES,
& Token); if( Result != TRUE ) {
printf( "Cannot open process token.\n" );
return FALSE;
} // Enable or disable? Info.Count = 1;
if( bEnable )
{
Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
}
else
{
Info.Privilege[0].Attributes = 0;
} // Get the LUID. Result = LookupPrivilegeValue ( NULL,
SE_LOCK_MEMORY_NAME,
&(Info.Privilege[0].Luid)); if( Result != TRUE )
{
printf( "Cannot get privilege value for %s.\n", SE_LOCK_MEMORY_NAME );
return FALSE;
} // Adjust the privilege. Result = AdjustTokenPrivileges ( Token, FALSE,
(PTOKEN_PRIVILEGES) &Info,
NULL, NULL, NULL); // Check the result. if( Result != TRUE )
{
printf ("Cannot adjust token privileges, error %u.\n", GetLastError() );
return FALSE;
}
else
{
if( GetLastError() != ERROR_SUCCESS )
{
printf ("Cannot enable SE_LOCK_MEMORY privilege, please check the local policy.\n");
return FALSE;
}
} CloseHandle( Token ); return TRUE;
}编译时候提示:
error C3861: “AllocateUserPhysicalPages”: 即使使用参数相关的查找,也未找到标识符
error C3861: “MapUserPhysicalPages”: 即使使用参数相关的查找,也未找到标识符
error C3861: “FreeUserPhysicalPages”: 即使使用参数相关的查找,也未找到标识符我在#pragma comment(lib, "advapi32.lib")下面加了下面几句:extern "C"_declspec(dllimport) BOOL AllocateUserPhysicalPages(
HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);extern "C"_declspec(dllimport) BOOL MapUserPhysicalPages(
PVOID lpAddress,ULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);extern "C"_declspec(dllimport) BOOL FreeUserPhysicalPages(
HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);
编译通过了,可是出现链接错误:
Dll_Memory_Control error LNK2019: 无法解析的外部符号 __imp__MapUserPhysicalPages ,该符号在函数 _Allocate_Memory 中被引用
Dll_Memory_Control error LNK2019: 无法解析的外部符号 __imp__AllocateUserPhysicalPages ,该符号在函数 _Allocate_Memory 中被引用
Dll_Memory_Control error LNK2019: 无法解析的外部符号 __imp__FreeUserPhysicalPages ,该符号在函数 _Free_Memory 中被引用第一次编dll文件,查了一些资料,还是找不到解决方法
#pragma comment(lib, "Kernel32.lib")
比如:
>>extern "C" _declspec(dllexport) void FreeMemory()
定义成void __stdcall FreeMemory()使用.def文件来导出函数,不要使用extern "C" _declspec(dllexport)这种形式,这种形式只是用在c和c++写的DLL和应用程序中的!你使用Delphi来调用DLL,所以最好的方式就是把导出函数写在.def文件的EXPORTS节下面
例如:
EXPORTS
FreeMemory
参考下:
http://comcamp.myrice.com/techarticles/vc/0001.htm
除了zhucde说的,你把user32.lib也加进去试试
解决了
没有缺少某个lib库
是因为在stdafx.h下面的一些和windows定义有关
我删除了_WIN32_WINDOWS和_WIN32_IE的定义
定义 _WIN32_WINNT 0x0502 用来匹配使用的操作系统
根据MSDN的说法我使用的三个内存操作函数要定义这个的
原来不知道stdafx.h文件的使用
我删除了
extern "C"_declspec(dllimport) BOOL AllocateUserPhysicalPages(
HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);extern "C"_declspec(dllimport) BOOL MapUserPhysicalPages(
PVOID lpAddress,ULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);extern "C"_declspec(dllimport) BOOL FreeUserPhysicalPages(
HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR UserPfnArray);
语句
根据vcforever(霓裳羽衣)的建议
我会修改源程序的
谢谢大家!