显式链接dll问题

powerhome 2004-03-24 09:23:35
我在程序中显式链接dll,但是调用完毕后,总是出错,跟踪一看是删除某个对象时出错。
那位大虾解决一下。
代码:
typedef void (*pSnippet) (char* path, string& text, string& query, string& snip);
HINSTANCE hDLL;
pSnippet snippet;
hDLL = LoadLibrary("Dll3.dll");
snippet = (pSnippet)GetProcAddress(hDLL,"Snippet");
char* path = "../config";
string query = m_query.GetBuffer();
m_query.ReleaseBuffer();
string body = mwmi.m_szBody.GetBuffer();
mwmi.m_szBody.ReleaseBuffer();
string snip ;
(*snippet)(path,body,query,snip);
FreeLibrary(hDLL);
...全文
56 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
taogx 2004-03-27
  • 打赏
  • 举报
回复
不能用string或string&作形参
好像是常识
用作形参 string没有初始化
Northeast 2004-03-27
  • 打赏
  • 举报
回复
不可能
我在DLL中的输出函数是
LPVOID TranslateStr(CString& pParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
pParam="Love";
return 0;
}
在EXE中调用代码如下
void C**View::OnDllTest()
{
CDC * pDC=GetDC();
HINSTANCE hInstance;
typedef LPVOID(* STR_FUNC)(CString&);//请注意此处的定义
STR_FUNC pFunction;
VERIFY(hInstance=::LoadLibrary ("F:\\Eniac\\Test\\Test2\\DLL\\Debug\\DLL.dll"));

VERIFY(pFunction=(STR_FUNC )::GetProcAddress(hInstance,"TranslateStr"));
CString pString;
(* pFunction)(pString);//请注意此处的调用
VERIFY(FreeLibrary(hInstance));
pDC->TextOut (40,140,pString);
ReleaseDC(pDC);
}
结果可以输出Love
我试过的,不信楼上的和楼主也可以试一下
dafan 2004-03-27
  • 打赏
  • 举报
回复
在函数调用的时候,直接用函数名就可以了吧,所以在“(*snippet)(path,body,query,snip)”这里,直接写成snippet(path,body,query,snip)应该可以的,我的程序就是这样用的啊,^_^,希望各位笑纳!!!因为我也是刚学这个DLL啊,很多问题还需各位的帮忙解决啊,先谢啦!
powerhome 2004-03-26
  • 打赏
  • 举报
回复
单步调试发现调用dll中的snippet函数时,实参的值没有传给形参,很奇怪。
下面是dll中的函数定义

void Snippet(char* path,string& text , string& query , string& snip)
{
Snippet4NG* pSnippet = new Snippet4NG();
pSnippet->Init(path);
pSnippet->GenerateSnippet(text,query,snip,"<b>","</b>");
}
powerhome 2004-03-26
  • 打赏
  • 举报
回复
我已经解决问题了,对dll中的函数进行调用时,不能用string或string&作形参,而只能用string*
修改程序如下
Snippet (char* path, string* body, string* query, string* snip )
所有问题ok
Northeast 2004-03-25
  • 打赏
  • 举报
回复
呵呵,概念错误
不好意思,新手上路,请勿见怪
我想应该是
string snip ;此处的snip没有赋初值,而引用是要赋初值的
(*snippet)(path,body,query,snip);
nooning 2004-03-25
  • 打赏
  • 举报
回复
不写 __stdcall 就会使用默认的C++风格,被调用的函数关心堆栈当前情况对调用者传入的参数不作清除,这样堆栈就会发生错位,当然结果会出错。
__stdcall就不一样了,函数会清除调用者传入的堆栈段,或者用POP退栈,或者用RET N方式。

通常你用DEPENDS看到函数名不是abc@xxx的,就是用stdcall,所以要用stdcall
powerhome 2004-03-25
  • 打赏
  • 举报
回复
楼上说错了吧,那样写不就成了传地址了么
Northeast 2004-03-25
  • 打赏
  • 举报
回复
(*snippet)(path,body,query,snip);
用(*snippet)应该是没有问题的
但是
typedef void (*pSnippet) (char* path, string& text, string& query, string& snip);后面三个参数声明的是string& 而你调用的时候直接是string
应该改为(*snippet)(path,&body,&query,&snip);
应该就没有问题了啊
powerhome 2004-03-25
  • 打赏
  • 举报
回复
按照flyelf的改过之后,执行snippet(path,body,query,snip)的时候报错

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention
rivershan 2004-03-25
  • 打赏
  • 举报
回复
请写出错误代码等~
xenke 2004-03-25
  • 打赏
  • 举报
回复
同意两星级人物的观点,照他的做没错!
Northeast 2004-03-25
  • 打赏
  • 举报
回复
应该没有错的啊
是不是在Snippet函数里出错了啊
Snippet里面都做什么了啊
powerhome 2004-03-25
  • 打赏
  • 举报
回复
我没有自定义析构函数,也没有显式调用过string的析构函数
xstring 2004-03-25
  • 打赏
  • 举报
回复
你把string类的析构函数贴出来
bauhaus 2004-03-25
  • 打赏
  • 举报
回复
??????????????????/
powerhome 2004-03-25
  • 打赏
  • 举报
回复
我没有include<string>,就直接用string声明了变量
xstring 2004-03-25
  • 打赏
  • 举报
回复
string是你自己定义的类么?
还是使用的 #include <string>里面的
powerhome 2004-03-25
  • 打赏
  • 举报
回复
就是snip析构出错,我把snip说明为全局变量后,则在程序退出时出错,所以判断为析构出错。
xstring 2004-03-25
  • 打赏
  • 举报
回复
是不是snip析构时出错?
加载更多回复(9)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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