关于DLL的两个小问题

zhangyan_qd 2003-03-03 04:26:30
以前DLL接触很少,今天在学习DLL的基本使用,编了一个小程序做试验。结果发现了两个问题:

1. 为什么导出函数的名字变成了_TextOutMe@16这么怪?是C++编译的需要吗?能否简单介绍一下关于导出函数命名变化的问题?

2. DEBUG版程序结束退出时,发生错误:

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 conversion with a function pointer declared with a different calling conversion.

不太明白是什么意思,能否请高手指点一二?

===============================================

附:我的程序代码
///////////////////////////////////////////////////
//DLLMe.h
//
///////////////////////////////////////////////////
#include <string>

#ifdef __cplusplus
#define EXPORT extern"C" __declspec(dllexport)
#else
#define EXPORT __declspec(dllexport)
#endif

using namespace std;

EXPORT BOOL CALLBACK TextOutMe(const string);

///////////////////////////////////////////////////
//DLLME.cpp
//
///////////////////////////////////////////////////

#include <windows.h>

#include <iostream>
#include <string>

#include "DLLMe.h"

using namespace std;

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID pvReserved)
{
return TRUE;
}

EXPORT BOOL CALLBACK TextOutMe(const string str)
{

cout << "DLL:" << str << endl;
return TRUE;
}

////////////////////////////////////////////////////////
//DllMeTry.cpp
//
////////////////////////////////////////////////////////
#pragma once
#include <windows.h>
#include <iostream>
#include <string>
#include <tchar.h>
#include "DLLMe.h"

using namespace std;

typedef BOOL(* FNP)(const string);
HINSTANCE hLib;
FNP pfnTextOut;
main()
{
string str;
cin >> str;
hLib = LoadLibrary(_T(str.c_str()));
if(hLib == NULL)return 0;
pfnTextOut = (FNP)GetProcAddress(hLib, _T("_TextOutMe@16"));
if(pfnTextOut == NULL)return 0;

while(str != "quit")
{
cin >> str;
pfnTextOut(str);
}

FreeLibrary(hLib);

return 0;
}
...全文
58 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangyan_qd 2003-03-04
  • 打赏
  • 举报
回复
whoo(谁) :我试过了,加CALLBACK之后问题解除,但extern"C"是不对的,语法错误。
谢谢!
zhangyan_qd 2003-03-04
  • 打赏
  • 举报
回复
whoo(谁) :赞!高手!
之所以两种方法混用,是因为我先试验的静态加载,又试验动态加载,忘记去掉了。
demetry 2003-03-04
  • 打赏
  • 举报
回复
最好写一个.DEF文件
whoo 2003-03-03
  • 打赏
  • 举报
回复
FNP
好像还少了个CALLBACK.
MyCrooner 2003-03-03
  • 打赏
  • 举报
回复
第一个问题,声明函数时要extern "c", 防止C++编译器更改函数名称.
esiedull 2003-03-03
  • 打赏
  • 举报
回复
观望
whoo 2003-03-03
  • 打赏
  • 举报
回复
晕,有DLL头文件而且也包含了,为什么还要用LoadLibrary.....
两种调用方法混在一起了。

如果你直接调用TextOutMe就应该没问题了。

如果非要LoadLibrary......的话,你的FNP声明有问题。

错误的意思是函数的调用声明不一致,例如c调用的函数被你当作pascal调用使用。调用的类型决定了参数入栈的顺序是从左到右还是从右到左。是调用方还是被调用方负责清理堆栈。

你的函数只有一个参数,从左到右还是从右到左都是一样的。所以碰巧能正常运行。
退出时清理栈的时候发生了矛盾。于是就报错了。

FNP的声明少了个extern "C".
brightwang 2003-03-03
  • 打赏
  • 举报
回复
你应该第一一个Def文件,这样编译器就不会修改你的函数名称。
foxustc 2003-03-03
  • 打赏
  • 举报
回复
唉,我试了一下你的代码,我对于第二个问题的解决办法不起作用.
等待高手来回答吧.
gz
up
foxustc 2003-03-03
  • 打赏
  • 举报
回复
第二个问题:
main()
{
string str;
cin >> str;
hLib = LoadLibrary(_T(str.c_str()));
if(hLib == NULL)return 0;
pfnTextOut = (FNP)GetProcAddress(hLib, _T("_TextOutMe@16"));
~~~~~~~~~~~~~~~这里改为TextOutME
你再试一试.
if(pfnTextOut == NULL)return 0;

while(str != "quit")
{
cin >> str;
pfnTextOut(str);
}

FreeLibrary(hLib);

return 0;
}
foxustc 2003-03-03
  • 打赏
  • 举报
回复
第一个问题:
C++在对程序进行编译之前,是要对函数名称进行一些处理的,这没有什么可大惊小怪的.
主要原因是为了支持C++中的函数重载和多态.

15,471

社区成员

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

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