如何动态调用DLL。。。。(使用LoadLibrary()函数)

nanbingjun2000 2003-03-28 05:24:45
1.我用VC做了基于Win32的Dll(sample.dsw,sample.c,sample.h,sample.def ),
2.编译后产生(sample.dll , sample.lib)
3.做了个测试程序(Demo.dsw,Demo.c Demo.h),在项目里加入了(sample.h)文件。
4,编译 Demo.dsw, 连接时出现下列错误,
Demo.obj : error LNK2001: unresolved external symbol "__declspec(
dllimport) int __cdecl ShowMe(void)" (__imp_?howMe@@YAHXZ
)
Debug/Demo.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.





...全文
414 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
qilinmaster 2003-03-29
  • 打赏
  • 举报
回复
总结得好,收藏,给分呀:)
nanbingjun2000 2003-03-29
  • 打赏
  • 举报
回复
up
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
TO: ckacka(小红帽)

谢谢小红帽的帮助!!!刚才这个问题已解决!!!多亏ckacka兄鼎立相助。。。再次感!!!

总结一下:

刚才我编译Demo.dsp时,刚开始是在工程文件里没有加入了生成sample.dll时生成的
sample.lib文件,然后在示例程序(Demo.exe)里直接调用了DLL中的函数ShowMsg(),
这使得在编译Demo.dsp时总是显示连接错误。。。
但后来加入后成功...

结果:
这时的dll的加裁方式是[隐式连接](在示例程序加裁就把DLL映射进了 进程的地址空间)

当我把示例程序(Demo.exe)里直接调用了DLL中的输出函数ShowMsg()取掉以后,
自然sample.lib文件也没有用,取了。。。
用ckacka兄的GetProcAddress()函数来取得dll中的输出函数时,编译正确。。。

结果:
这时的dll的加裁方式是[显示连接](在示例程序中调用WIN32API LoadLibrary()函数时
动态的把DLL文件映射进了进程的地址空间)

*** 达 到 目 的 ***
多谢!多谢!
请ckacka留下联系方式,以便日后继续切磋!!!
我的qq : 29142555
msn : nanbingjun@hotmail.com
email : nanbingjun@soho.com





ckacka 2003-03-28
  • 打赏
  • 举报
回复
呵呵!

dllmain不是一个被调用的函数,只是一个entery point

BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;

case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;

case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;

case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
up
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
up
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
什么叫一起读入?你先看看书吧!》》

我说的一起读入是:
当操作系统加入Exe文件时,系统按照Exe文件映像中的内容来查看要装入那些dll,
而后系统将需要的DLL文件映像映射到进程的地址空间中。
而后系统将调用dll的入出口函数DLLMAIN,传递参数为DLL_PROCESS_ATTACH(只在映射首次发生
时。。。)
所以在 DLL_PROCESS_ATTACH分支里的我的函数(MessageBox("Dll Load!!!"))被调用了,,

* 这就是我所说的一起调用 *

但我要的不是在示例应用程序开始执行时,调用库的dllmain(),而是在调用LoadLibrary()
函数时执行dllmain()函数的DLL_PROCESS_ATTACH分支里的我的函数
ckacka 2003-03-28
  • 打赏
  • 举报
回复
>>但程序读入时一起读入DLL

什么叫一起读入?你先看看书吧!

The Old Way
According to "About Dynamic Link Libraries" in the Platform SDK, there are two methods for calling DLLs:

"In load-time dynamic linking, a module makes explicit calls to exported DLL functions. This requires you to link the module with the import library for the DLL. An import library supplies the system with the information needed to load the DLL and locate the exported DLL functions when the application is loaded."
"In run-time dynamic linking, a module uses the LoadLibrary or LoadLibraryEx function to load the DLL at run time. After the DLL is loaded, the module calls the GetProcAddress function to get the addresses of the exported DLL functions. The module calls the exported DLL functions using the function pointers returned by GetProcAddress. This eliminates the need for an import library."
The two major benefits to using run-time linking are:

When the DLL is not available, an application using load-time dynamic linking simply terminates, while the run-time dynamic linking is able to respond to the error.
If the DLL changes, an application that uses load-time dynamic linking may again terminate, while an application linked at run-time is only affected if the desired functions are not present in the new DLL.
Run-time dynamic linking is not unlike querying interfaces in COM. It is more robust, however, and allows for more flexibility on the part of DLL provider and consumer. This article assumes that you will want to link DLLs using run-time dynamic linking.
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
问:
我在编译示例程序(Demo.c)时在项目里加入了dll的sampledll.lib文件和sampledll.h
头文件 (包含输出函数声明),编译正确。。。
但程序读入时一起读入DLL,
我想要的效果是在调用函数LoadLibrary()函数时才把dll文件显示的映射进程的地址空间。。。
???
ckacka 2003-03-28
  • 打赏
  • 举报
回复
// Get adress for CreateInstance function.
CREATEFUNCPTR CreateInstance
= (CREATEFUNCPTR)::GetProcAddress(hComponent, "CreateInstance");
ckacka 2003-03-28
  • 打赏
  • 举报
回复
你都没有得到地址,怎么可能调用!
ckacka 2003-03-28
  • 打赏
  • 举报
回复
多余?我已经说过了,这是方法之一
把你的代码贴出来看看
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复

我的文件结构:

Demo.cpp

void CDemoDlg::OnLoad()
{
// TODO: Add your control notification handler code here
if(hdll != NULL)
{
MessageBox("dll alery Load!!!\n");
return;
}

hdll = LoadLibrary("sample.dll"); //loading DLL

ShowMe(); //call dll export function

return;
}

sample.h


#if !defined(DLLAPI)
#define DLLAPI _declspec(dllimport)
#endif

extern DLLAPI int ShowMe(void);


nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
up
ckacka 2003-03-28
  • 打赏
  • 举报
回复
// Load dynamic link library into process.
HINSTANCE hComponent = ::LoadLibrary(name);

我不是说了吗?这样用!看上面的代码
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
ckacka(小红帽) :
我理解是IDL(接口定义语言)是在vc里做的DLL, 在VB,COBOL,Delphi调用是才有用,
我的 DLL 和 调用端都是用vc 做的,这里好象用IDL,未必多余了吧?

等待中。。。
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
楼上兄:
我想问为什么会出现连接错误!!!
我在编译时在工程里加入了相关DLL的Lib文件。 编译正常,
但dll是在应用程序load时一起装入内存,我的意愿是让他在调用相关函数时调入。。。
ckacka 2003-03-28
  • 打赏
  • 举报
回复
编译阶段可以不知道dll文件,但是应该知道他的接口,其实这样说也是不准确的,我们应该用代码来查询可能(已知)接口
ckacka 2003-03-28
  • 打赏
  • 举报
回复
这个是一个基于原理的示例

你的程序需要知道接口定义,可以象我写的"CREATE.H"

也可以象IDL那样
nanbingjun2000 2003-03-28
  • 打赏
  • 举报
回复
在线等待中...
加载更多回复(4)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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