动态调用DLL文件的问题...提示非法指针操作!(急!!全天在线等!!)
typedef AnsiString __stdcall TPUT(AnsiString data,int index); //新类型 TPUT
HINSTANCE d;//定义模块句柄
d=LoadLibrary("Output.dll");//装入Output.dll文件,同时获得它的句柄
if(d!=NULL)
{
TPUT *Put=(TPUT *)GetProcAddress(d,"PutData");
if(Put!=NULL)
Memo2->Text=Put("talkingmute",0);
else
ShowMessage("调用Output.dll中的PutData函数失败!");
}
else
ShowMessage("打开Output.dll失败!");
FreeLibrary(d);//释放DLL
在动态调用DLL文件的事件发生时,打开dll文件和调用PutData函数都没问题,但是就提示"invalid pointer operator",然后程序就挂了...
请问这里哪里出错了!!谢谢大家!!
问题点数:50、回复次数:11Top
1 楼MEFULEU(没有作不到,只有想不到)回复于 2005-05-19 12:02:04 得分 10
http://community.csdn.net/Expert/TopicView3.asp?id=4017084Top
2 楼MEFULEU(没有作不到,只有想不到)回复于 2005-05-19 12:02:50 得分 10
typedef void _stdcall _export (*TShowstr);
TShowstr mShowstr;
HINSTANCE hInst=::LoadLibrary("MyFun.dll");
if(!hInst)
{
ShowMessage("Failed to load library");
return;
}
else
{
mShowstr=(TShowstr)GetProcAddress(hInst,"Showstr");
if(mShowstr)
{
mShowstr();
}
else
{
ShowMessage("Failed to locate the function you specified");
}
::FreeLibrary(hInst);
}Top
3 楼rd73()回复于 2005-05-19 15:15:10 得分 0
你在DLL中传递CB的AnsiString行不行啊? 为什么不用char *呢? 在VC的动态库中要用到MFC,也要特殊支持才行.
我平时做DLL,都是用C的标准变量来传递参数,没用过类做参数,这样的DLL会更通用一些。Top
4 楼jishiping(JSP 季世平)回复于 2005-05-19 15:15:26 得分 20
1、首先确认一下,Put 是否为 NULL。如果你没有使用 extern "C",那么DLL中的函数名,可能不是PutData,而是_PutData,此时得到的函数指针 Put 为NULL,当然会出错。
2、你的DLL和EXE是否使用静态连接(就是不需要BCB的BPL以及DLL就可以独立运行)?也就是菜单Project|Options中的Packages页面的“Build with runtime packages”前没有打勾。如果是这样的话,需要在DLL以及EXE的project中,增加MEMMGR.LIB才可以,否则会出错。Top
5 楼yifei1900(逸飞)回复于 2005-05-19 15:24:57 得分 0
我原创:
http://www.myideas.cn/homepage/index.php?option=com_content&task=view&id=60&Itemid=46Top
6 楼talkingmute(CS-{Z})回复于 2005-05-20 10:10:18 得分 0
哦,我知道了,是因为AnsiString类型的缘故,可那些英文,看的不是很懂...
不知能否帮忙给解释下??Top
7 楼leonatcs(LeonKennedy)(时常逛一逛csdn,有益身心健康。)回复于 2005-05-20 11:35:06 得分 10
整天看到那段话,都当耳旁风了!
我就没想到。
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
当dll使用静态RTL时关于内存管理重要说明:
如果你的dll提供了参数中或返回值中有String对象(或包含String对象的类或结构体)
的输出函数,你必须加载MEMMGR.LIB到你的dll工程及调用dll的工程。
还有,如果调用dll的工程new或者delete了任何该dll提供的非TObject子孙类,也需要加载MEMMGR.LIB。
加载MEMMGR.LIB会使得dll及其调用者使用BORLNDMM.DLL作为他们的内存管理器。
所以,你需要把BORLNDMM.DLL和你的dll放在一起发布。
改用“char *”或者ShortString做参数可以避免BORLNDMM.DLL的使用。
如果你的dll使用动态RTL,你不需要显式的加载MEMMGR.LIB,BCB隐式的为你做了此工作。Top
8 楼leonatcs(LeonKennedy)(时常逛一逛csdn,有益身心健康。)回复于 2005-05-20 11:39:58 得分 0
为人民服务,翻译了一下那段:)Top
9 楼xukaiming(许开明)回复于 2005-05-27 18:10:30 得分 0
翻译得不错,文达雅Top
10 楼yifei1900(逸飞)回复于 2005-05-29 20:50:27 得分 0
另外,
在调用动态链接库的时候,
如果导出函数需要一定量的缓冲区,
如果你申请少了的话,
也有可能函数调用成功,但是提示非法指针操作的。Top
11 楼talkingmute(CS-{Z})回复于 2005-05-30 09:04:00 得分 0
to: yifei1900(逸飞)
有些模糊,需要一定量的缓冲区,可否仔细说下呢?函数的导出还需要缓冲区??还要申请??
请指点!
Top




