(求助)DLL导出函数问题

Joker____ 2011-08-14 02:08:42
MyDLL.dll 我自己写的一个DLL文件 里面有

__declspec(dllexport) DWORD ExportExample(LPSTR szMSG,DWORD dwCode);

DWORD ExportExample(LPTSTR szMSG,DWORD dwCode)
{
LPTSTR lpShowOut = (LPTSTR)HeapAlloc(GetProcessHeap(),NULL,lstrlen(szMSG)+100);
wsprintf(lpShowOut,TEXT("%s,%d"),szMSG,dwCode);
MessageBox(NULL,lpShowOut,TEXT("ExportExample"),MB_OK);
HeapFree(GetProcessHeap(),NULL,lpShowOut);
return 0;
}

然后我在我另外一个工程中 成功导入了DLL(我写了导入时弹出对话框)

LoadLibrary(L"D:\\MyDLL.dll");

pfnShow pfn = (pfnShow) GetProcAddress(GetModuleHandle(L"MyDLL"),"ExportExample");
if (pfn == NULL)
{
printf("GetProcAddress Error : %d\n",GetLastError());
return -1;
}

pfn(TEXT("message"),12);
return 0;

但是每次pfn的值都为NULL 请问这个是什么原因。。。3Q~~~
...全文
555 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
blackkettle 2011-08-15
  • 打赏
  • 举报
回复
学习了。
cswuyg 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 joker____ 的回复:]

谢谢各位帮忙 已经添加DEF到工程 重新生成DLL 成功!

另外能不能告诉一下 为什么我
extern "C" __declspec(dllexport) DWORD __stdcall ExportExample(LPSTR szMSG,DWORD dwCode);
这样写 不写DEF文件 还是不能找到呢?
而我看的例子 只有
__declspec(dllexport) DWO……
[/Quote]
1、
__stdcall,无论C还是C++都会Name Mangling,这样dll的导出表里的函数名就不是你在程序里写的那个函数名了。
.def文件可以对导出函数命名,无视Name Mangling。


2、
__declspec(dllexport) DWORD ExportExample(LPSTR szMsg, DWORD dwCode);
采用默认的调用约定,采用默认的Name Mangling。“直接导入”,GetProcAddress?难道是C的?
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 linghu9990 的回复:]

引用 26 楼 joker____ 的回复:

谢谢各位帮忙 已经添加DEF到工程 重新生成DLL 成功!

另外能不能告诉一下 为什么我
extern "C" __declspec(dllexport) DWORD __stdcall ExportExample(LPSTR szMSG,DWORD dwCode);
这样写 不写DEF文件 还是不能找到呢?
而我看的例子 只有
……
[/Quote]

好的。。。3Q 结贴了~
towriting 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 joker____ 的回复:]

谢谢各位帮忙 已经添加DEF到工程 重新生成DLL 成功!

另外能不能告诉一下 为什么我
extern "C" __declspec(dllexport) DWORD __stdcall ExportExample(LPSTR szMSG,DWORD dwCode);
这样写 不写DEF文件 还是不能找到呢?
而我看的例子 只有
__declspec(dllexport) DWO……
[/Quote]
看看《程序员的自我修养》
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
谢谢各位帮忙 已经添加DEF到工程 重新生成DLL 成功!

另外能不能告诉一下 为什么我
extern "C" __declspec(dllexport) DWORD __stdcall ExportExample(LPSTR szMSG,DWORD dwCode);
这样写 不写DEF文件 还是不能找到呢?
而我看的例子 只有
__declspec(dllexport) DWORD ExportExample(LPSTR szMsg, DWORD dwCode);
一行 却可以在自己的程序中直接导入呢~
kakawoshishui 2011-08-14
  • 打赏
  • 举报
回复
你最好查看一下dll导出函数的名字,如果你用的是c++,那么c++编译器会对函数名进行改编,当你用getprocaddress获得函数地址时,传入的名字可能找不到,前提你的DLL句柄不是空的,

如果你用c++写的dll,那么可以在__declspec(dllexport)前边加extern "C"源文件必须是c++
或者更简单的是添加一个.def模块文件,这个文件会抑制函数名字的改编。
SonicLing 2011-08-14
  • 打赏
  • 举报
回复
GetModuleHandle():
If lpModuleName does not include a path and there is more than one loaded module with the same base name and extension, you cannot predict which module handle will be returned. To work around this problem, you could specify a path, use side-by-side assemblies, or use GetModuleHandleEx to specify a memory location rather than a DLL name.


最好把LoadLibrary的返回值传给GetProcAddress(),要用GetModuleHandle也把名字写精确,否则,如果你的exe叫做MyDLL.exe,他有可能返回exe的handle。

这只是我对问题的猜测,如果你用DependWalker查过,并确定导出函数名没问题的话。
towriting 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 joker____ 的回复:]

已经新建文件MyDLL.dll在MyDLL工程下 文件内容如下

LIBRARY "MyDLL"

EXPORTS
ExportExample

清理后重新生成 然后拷到D盘覆盖原有DLL(新DLL大了0.5KB)
仍然没用。。。
头痛。
[/Quote]
应该将mydll.def 文件加入到工程中
Waistcoat23 2011-08-14
  • 打赏
  • 举报
回复
你google “vc 编写DLL”
Waistcoat23 2011-08-14
  • 打赏
  • 举报
回复
这个def文件添加到工程里了吗?
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
已经新建文件MyDLL.dll在MyDLL工程下 文件内容如下

LIBRARY "MyDLL"

EXPORTS
ExportExample

清理后重新生成 然后拷到D盘覆盖原有DLL(新DLL大了0.5KB)
仍然没用。。。
头痛。

Joker____ 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 sonicling 的回复:]

__declspec(dllexport) DWORD ExportExample(LPSTR szMSG,DWORD dwCode);
__declspec(dllexport) DWORD __cdecl ExportExample(LPSTR szMSG,DWORD dwCode);
__declspec(dllexport) DWORD __stdcall ExportExample……
[/Quote]

就是说我还得去MyDLL.dll里面再写个MyDLL.def咯 然后重新编译?
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 linghu9990 的回复:]

引用 15 楼 joker____ 的回复:

引用 13 楼 waistcoat23 的回复:

http://www.dependencywalker.com/


我查过了 一打开我写的DLL 出现

警告: 至少有一个延时加载模块没找到。
警告: 由于在延时加载依赖模块中丢失导入函数,至少有一个模块具有不能解析的导入。

这个是?。。。

这个先不管,导出函数……
[/Quote]

看不到 左边两个框框都是白的。。。
towriting 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 joker____ 的回复:]

引用 13 楼 waistcoat23 的回复:

http://www.dependencywalker.com/


我查过了 一打开我写的DLL 出现

警告: 至少有一个延时加载模块没找到。
警告: 由于在延时加载依赖模块中丢失导入函数,至少有一个模块具有不能解析的导入。

这个是?。。。
[/Quote]
这个先不管,导出函数名对不对,看不到吗,exesc也可以看导出函数名!
SonicLing 2011-08-14
  • 打赏
  • 举报
回复
__declspec(dllexport) DWORD ExportExample(LPSTR szMSG,DWORD dwCode);
__declspec(dllexport) DWORD __cdecl ExportExample(LPSTR szMSG,DWORD dwCode);
__declspec(dllexport) DWORD __stdcall ExportExample(LPSTR szMSG,DWORD dwCode);
extern "C" __declspec(dllexport) DWORD __cdecl ExportExample(LPSTR szMSG,DWORD dwCode);
extern "C" __declspec(dllexport) DWORD __stdcall ExportExample(LPSTR szMSG,DWORD dwCode);

他们的导出符号是不同的,编译器可能会自动给他们添加前缀和后缀来代表参数、重载、返回值等信息。

可以在DLL的工程里使用def文件来明确每个函数的导出符号。你指定的导出符号可以和函数名没关系。
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 waistcoat23 的回复:]

http://www.dependencywalker.com/
[/Quote]

我查过了 一打开我写的DLL 出现

警告: 至少有一个延时加载模块没找到。
警告: 由于在延时加载依赖模块中丢失导入函数,至少有一个模块具有不能解析的导入。

这个是?。。。
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 waistcoat23 的回复:]

http://www.dependencywalker.com/
[/Quote]

3Q~我去查一下~
Waistcoat23 2011-08-14
  • 打赏
  • 举报
回复
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 linghu9990 的回复:]

你用工具看看你的DLL的导出名是不是ExportExample
[/Quote]

用什么工具看嗯?导出名不是和自己定义时候的名字一样的么?
Joker____ 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 linghu9990 的回复:]

Remarks
The GetProcAddress function is used to retrieve addresses of exported functions in DLLs.

The spelling and case of the function name pointed to by lpProcName must be identical to that in ……
[/Quote]

没有。。。
__declspec(dllexport) DWORD ExportExample(LPSTR szMSG,DWORD dwCode);
这句话不是把这个函数导出了么?
加载更多回复(10)

15,471

社区成员

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

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