如何在 BCB 的 DLL 中创建共享内存段?

shadowstar 2002-09-07 08:06:26
原文来自: http://bdn.borland.com/article/

How to create a shared segment in a dll. - by Borland Developer Support Staff




Abstract:Gives an example of creating a shared segment in Builder4 using compiler switches and DEF file.
Question:
How do I build a dll that contains a shared data segment? Books I've been reading mention the #pragma data_seg() directive, but this doesn't seem to be supported by Builder.

Answer:
Builder 4 does not support the #pragma data_seg() directive, but there are compiler switches that will, along with the proper .def file, allow you to do this.

You will have to put the data you want shared in it's own source file and use the -zR and -zT compiler switches. These switches change the data segment name and class name for whatever source file they are used in. You will have to initialize the data you want to share, as uninitialized data is automatically moved to the default data segment. You must also create a .def file for your dll that tells the linker to give that segment the shared property.

Example:
There are four files in this example:

dll.h // foreward declarations for the dll
dllmain.cpp // the CPP file that contains the dll entrypoint
dllshared.cpp // contains the shared data
dlldef.def // module definition file for the dll

#pragma hdrstop
#include
#define __dll__
#include "dll.h"

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
\{
return 1;
\}

extern int SharedInteger;

int GetInteger(void)
\{
return SharedInteger;
\}

void SetInteger(int arg)
\{
SharedInteger = arg;
\}

//---- end file dllmain.cpp ----//




//---- begin file dllshared.cpp ----//

#pragma option -zRSHARESEG // sets segment name for this source file to SHARESEG
#pragma option -zTSHARECLS // sets class name for segment to SHARECLS

int SharedInteger = 0;

//---- end file dllshared.cpp ----//



//---- begin file dlldef.def ----//

LIBRARY DLLMAIN

SEGMENTS
SHARESEG CLASS "SHARECLS" SHARED

//---- end file dlldef.def ----//








--------------------------------------------------------------------------------

Add or View comments on this article


Products:
Borland C++ Builder 4.0

Platforms:
Windows NT 4.0

Article ID: 20132 Publish Date: November 24, 1999 Last Modified: May 10, 2000

也可去看 cker 翻译的: http://www.csdn.net/Develop/read_article.asp?id=7300


这个例子我已经测试通过, 但我的程序却总是报错
下面是我的部分代码:
//---- begin file dlldef.def ----//

LIBRARY DLLMAIN

SEGMENTS
SHARESEG CLASS "SHARECLS" SHARED

//---- end file dlldef.def ----//


//---- begin file dllshared.cpp ----//
#pragma option -zRSHARESEG // sets segment name for this source file to SHARESEG
#pragma option -zTSHARECLS // sets class name for segment to SHARECLS

DWORD g_dwShare = 0;

错误提示: [C++ Error] dllshare.cpp(5): E2141 Declaration syntax error

如果在第一行加入
#include <windows.h>
错误提示:
[C++ Error] dllshare.cpp(3): E2075 Incorrect pragma directive option: -zRSHARESEG

如果在第三行加入
#include <windows.h>
错误提示:
[Linker Error] Section SHARESEG defined in .def file is empty

...全文
148 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
shadowstar 2002-09-08
  • 打赏
  • 举报
回复
糊涂啊, 挨打……

以后不敢这么马虎了

偶把extern变量后面跟上=了@@

感谢各位参与讨论!
NowCan 2002-09-08
  • 打赏
  • 举报
回复
但是建议使用FileMapping
NowCan 2002-09-08
  • 打赏
  • 举报
回复
1)用FileMapping
2)http://vip.6to23.com/NowCan1/tech/bcbhook.htm
lj_csdn 2002-09-07
  • 打赏
  • 举报
回复
比较一下编译选项。
我倒是遇到好多次这种情况。重建工程,把代码装进去就行了
shadowstar 2002-09-07
  • 打赏
  • 举报
回复
我也不明白,写了个新的,真的是好的!
  • 打赏
  • 举报
回复
哎,不明白。
我刚写了一个新的,还是好的么...
shadowstar 2002-09-07
  • 打赏
  • 举报
回复
to: cker(〖烟波浩淼三千里、人鬼殊途五百年〗)
嗬嗬,好热闹啊
to shadowstar:
把你那个通不过的工程发给我呗.
cker#sina.com


我再试一下, 在例子里加上我的代码就对了
我想有可能是文件载入的先后顺序,或是和文件名什么的有关
shadowstar 2002-09-07
  • 打赏
  • 举报
回复
昨天我已经试过了,和单引号还是双引号无关!
  • 打赏
  • 举报
回复
//---- begin file dlldef.def ----//

LIBRARY DLLMAIN

SEGMENTS
SHARESEG CLASS "SHARECLS" SHARED

//---- end file dlldef.def ----//
兄弟,好像这里应该用单引号呗...
是不是这个原因啊,你试试先...

SHARESEG CLASS 'SHARECLS' SHARED
  • 打赏
  • 举报
回复
嗬嗬,好热闹啊
to shadowstar:
把你那个通不过的工程发给我呗.
cker#sina.com
shadowstar 2002-09-07
  • 打赏
  • 举报
回复
可不可以用我上面说的方式, 我只是想研究一下!
例子完全可以的呀
lj_csdn 2002-09-07
  • 打赏
  • 举报
回复
注:
创建:在DLL中执行
引用:在其他程序中执行
jishiping 2002-09-07
  • 打赏
  • 举报
回复
这是我写的一个共享内存的class。
class TSharedMem
{
private:
int FSize;
bool FCreated;
BYTE *FFileView;
HANDLE Handle;
AnsiString FName;
public:
TSharedMem(LPCSTR Name, int Size);
~TSharedMem();

__property int Size = {read=FSize};
__property bool Created = {read=FCreated};
__property BYTE* MemData = {read=FFileView};
__property AnsiString Name = {read=FName};
};

TSharedMem::TSharedMem(LPCSTR name, int size)
{
FSize = size; FName = name;
Handle = CreateFileMapping((HANDLE)0xFFFFFFFF,
NULL, PAGE_READWRITE, 0, size, name);
if (Handle == 0) {
FCreated = TRUE; FFileView = NULL;
}
else {
FCreated = GetLastError() == 0;
FFileView = (BYTE*)MapViewOfFile(Handle,
FILE_MAP_WRITE, 0, 0, size);
if (FFileView && FCreated)
ZeroMemory(FFileView, size);
}
}

TSharedMem::~TSharedMem()
{
if (FFileView) UnmapViewOfFile(FFileView);
if (Handle) CloseHandle(Handle);
}
lj_csdn 2002-09-07
  • 打赏
  • 举报
回复
使用API实现共享
创建:

HANDLE hMemObject = NULL;

BOOL InitShareMem(char *mem_name)
{ int i;
char *p;
hMemObject = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,MAX_BLOCK*sizeof(TVsatBlock),mem_name);
if (hMemObject == NULL) return FALSE;
p = (char *)MapViewOfFile(hMemObject,FILE_MAP_WRITE,0,0,0);
return TRUE;
}

引用:

int InitShareMem(char *mem_name)
{ int i,k,n;
char *p;
HookMem=OpenFileMapping(FILE_MAP_WRITE,TRUE,mem_name);
if (HookMem==NULL) return 0;
p =(char *)MapViewOfFile(HookMem,FILE_MAP_WRITE,0,0,0);
}

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧