火炬之光2运行提示 Failed to load loadlibrary failed"LIBEAY32.dll"

使用从DLL导出的类使用LoadLibrary_DLLs&组合_编程通用_或代码
| 文章 >> 编程通用 >> DLLs&组合
使用从DLL导出的类使用LoadLibrary
简介我见过不少,解释了如何使用在应用程序中的DLL导出类的代码很多。然而,所有这些描述隐式链接到DLL导出类的用法。刷新我们的DLL的概念,应用程序使用一个DLL中编写的函数有两种方式。第一种方式是您的应用程序的源代码,只是引用的DLL中的符号。这将导致装载机隐式负载(和链接)调用应用程序时所需的DLL。这被称为隐式链接。第二种方法是显式地加载所需的DLL(使用调用LoadLibrary()调用)和显式链接到应用程序运行所需的导出的符号,而应用程序。换句话说,如果应用程序决定它要调用DLL中的函数,它可以显式地加载到进程的地址空间的DLL,得到的DLL中包含的功能的虚拟内存地址,然后调用函数使用这个内存地址。这种技术的优点是,一切都是,而在应用程序运行和应用程序可以从进程的地址空间中卸载DLL时,它已完成其与该DLL的工作。正如您可能已经猜到了,这种技术被称为显式链接。背景到目前为止,我谈到了使用功能,但是,嘿,使用从DLL导出的类是什么?那么,在隐式链接的DLL的情况下,有没有区别。但是对于显式加载DLL,并使用导出类?那么,在正常情况下,它不能做,但我写这篇文章不是向你解释,为什么不能做,但你如何能做到这一点,给你一个想法。这就对了!!使用加载一个DLL使用调用LoadLibrary()调用导出类。,但在继续之前,我警告你,下面给出的方法是一个黑客的排序,并为任何原因,如果您计划在项目中使用它,请你的老板事先批准... (如果你管理得到他/她对这种技术的批准!)任何机会。不过,这列基本上是您的理解和极端的情况下,当你只是不能做无本hack。使用代码,如果你看一下示例代码,你可以看到我已经创建了一个计算器DLL称为Calc.DLL和我使用的计算称为UserOfCalc在我的控制台应用程序的DLL中的权力(我想不出一个更好的名字!).// Calc.DLL包含一个导出类/ /所谓的CCalc包含名为Add的3种方法,Sub和GetLastFunc()。它是如下:/ / CALC.H - 声明CCalc类/ /从DLL导出/ /和进口的EXE#包括LT; tchar.#IFDEF CALC_EXPORTS#定义CALC_API __declspec(dllexport)的#ELSE#定义CALC_API __declspec(dllimport)的#ENDIF#定义SOME_INSTN_BUF 260类CALC_API CCalc{私人:TCHAR m_szLastUsedFunc [SOME_INSTN_BUF];市民:
CCalc();
INT添加(INT I,j)的;
INT分(INT I,j)的;
TCHAR * GetLastUsedFunc();执行此DLL是显示在文件Calc.cpp中:# Calc.#包括LT; windows.BOOL APIENTRY DllMain中(句柄,DWORD,LPVOID){
返回TRUE;}/ /构造函数,初始化m_szLastFuncCalled阵列CCalc::CCalc(){
memset的(m_szLastUsedFunc,0,sizeof(m_szLastUsedFunc)的);
使用strcpy(m_szLastUsedFunc,"用yetquot无功能;);}INT CCalc:地址(INT,INT j){
使用strcpy(m_szLastUsedFunc,"添加);
返回(I J);}INT CCalc:分(INT,INT j)使用strcpy(m_szLastUsedFunc,"子);
返回(I - J);}现在,怎么办,我们使用这个Calc类中明确载入DLL的功能?步骤如下:第一步是在您的应用程序使用LoadLibrary来加载Calc.DLL库。 HMODULE hMod = LoadLibrary的("; Calc.dllquot";);如果(NULL == hMod){ &
printf的("LoadLibrary的失败\);
既然你的Calc.DLL的头文件,下一步是分配的内存块相匹配的一流布局,并调用构造函数代码。 CCalc * pCCalc =(CCalc *)malloc的(SIZEOF(CCalc));如果(NULL == pCCalc){&#1
的printf(内存分配失败\);
返回1;,但是,为什么在C世界我们使用,而不是新的malloc!!由于新的操作符调用CCalc的构造函数,而我们没有任何访问。请记住,我们有动态加载DLL,因此没有CCalc的构造函数在编译的时候提供给我们的定义。因此,我们只获得一个未初始化的内存块,其大小等于CCalc类的大小。如果你看看在DUMPBIN.EXE导出函数(即位于您的Microsoft Visual Studio \ VC98 \ Bin目录下),并键入DUMPBIN /出口,你会看到一个由DLL导出的函数列表。 (顺便说一下,我已经使用DEF文件unmangle错位的函数名。),这是图中所示。 该列表包含的虚拟内存地址的功能加入小组,GetLastUsedFunc和构造。由于我们得到的内存块,我们要调用的构造函数来初始化的内存块。所以,我们得到DLL.PCTOR pCtor的构造函数的相对虚拟地址=(PCTOR)GetProcAddress函数(hMod,"CC);如果(NULL == pCtor){
printf的("GetProcAddress的失败\);&
返回1;}PCTOR 是一个函数指针,是目前在UserOfCalc.cpp顶部。它的定义如下:类型定义无效(WINAPI * PCTOR)();既然我们已经构造函数的地址,我们必须显式调用它来初始化由malloc获取的内存块。没错,但怎么我们关联对象的构造?如果你还记得,当任何成员函数被调用,包括构造,对象的地址获取悄悄地传递给被调用的函数和这个地址存储在堆栈中。在一个基于Intel的机器,这个对象的地址是通过ECX寄存器压入堆栈。所以,如果你创建一个类并调用它的成员函数,ECX寄存器包含'这个'指针。这个屏幕快照,应该更清楚。 如果你观察后反汇编窗口,该行的执行:的LEA ECX,[EBP - 4]你会看到,ECX和内容"放大器;宝马"是相同的。有不同的处理器架构的机器,它可能是另一种,而不是ECX寄存器。我们只需要明白这一点。反观我们Calc.dll,因为我们已经有了一个内存块的地址(即在未来将是一个对象),我们移动到ECX寄存器通过使用Visual C内联汇编语法地址:__asm​​ {MOV ECX,pCCalc}既然我们已经获得了构造函数的地址,我们只是说:pCtor();从DLL中的函数指针pCtor()返回时,它会初始化在DLL中的类的对象。瞧!!要调用Calc类的任何其他成员函数,再次移动pCalc到ECX中,并取得PROC导出的函数地址,并简单地调用该函数。如果您在拆装任何简单的类,你会发现,任何成员函数调用之前,总是有汇编指令移动到ECX'这个'。这基本上是我们所做的工作。兴趣点如果通过源代码的单步,这个概念将更加清晰给你。为了解DLL的工作,请"或"高级Windows NT",杰弗里里氏书面参考"适用于Microsoft Windows编程应用"。他们真棒!!最后,这是我写的东西(anything!!)的第一枪。所以,我会得到真正的快乐,如果你喜欢阅读这篇文章,如果你觉得这是有用的。如果您有任何建议或批评,请随时邮件我。
关于作者:
中国我是一名编程爱好者,谢谢为我们提供一个学习和分享的平台。有什么问题。可以就本内容回复,我看到时。会尽量回复的。
评论会员:
时间:您是使用简单GetProcAddress函数("函数名"),当我预计你会使用GetProcAddress("decored_function_name")。 我知道,类的成员至少在Visual C 6名decored,甚至没有外部的"C"删除,装修。那么,为什么你有没有装修的DLL类出口?
编辑:我是用动态的DLL链接:P
10月8日修改'11 评论会员:
时间:您好
你在你的榜样UseOfCalc.exe例如
包括"Calc.h"
你需要包括H文件?我之所以问,是我想要做一些后期绑定在我的应用程序。我有一个客户端DLL导出函数。我希望能够设置一个接口等,我没有recomplie自己的应用程序每次我有一个客户端DLL。
我要与客户端设置一个预定的接触,函数签名应返回一个布尔,和采取任何输入参数。所以,如果我知道的功能名称,时间提前,我可以通过向aruguemnts tehm GetProcAddress的评论会员:
时间:这个伟大的articule首先感谢,生病帮助我很多,但如果我想使用一个回调函数从一个DLL,在执行一个可执行文件。有什么想法?BR}
感谢您的帮助评论会员:
时间:,这是不是一个理想的解决方案。SVRajkumar 评论会员:
时间:?的构造函数调用另一个成员函数其实,这是我看到的典型案例中的大多数代码:初始化分离一些"的init()"方法,它的构造函数调用。模仿能力 - 一个"重新启动"为现有的对象 - 一个构造的工作仅仅是有用的。
然后 - 可爱劈评论会员:
时间:您好Anup,
这是Adeel。这是一个伟大的文章。我想在我的项目中使用。然而,在使用之前,我还有一个要求。就像我们可以访问一个类的使用LoadLibarary,是可以将参数传递到一个出口类的成员函数?
感谢问候,AdeelMaverick 评论会员:
时间:大家好,
Anup说:"但是,为什么在彗星世界中是我们使用而不是新的malloc!!因为new运算符调用CCalc的构造函数为我们做不会有任何访问。记住,我们都来加载DLL的动态,并因此没有CCalc的定义构造函数在编译的时候提供给我们。"
我测试主体(顶部加入以下几行)。/ /开始我的测试CCalc * pCCalc2 =新CC INT KKK = pCCalc2 - GT;地址(2,5); printf的("KKK =%D. \ N",KKK); 删除pCCalc2; / /结束我的测试
它被编译和运行正常。它打印"KKK = 7。"
我使用Visual Studio 2005。我想加以解释为什么/如何我的测试工作。谢谢!
我的签名... ^ _ ^ 评论会员:
时间:我的猜测是,你的lib文件链接到您的代码,否则你会得到一个链接错误评论会员:
时间:这东西是很可怕的,但怎么办你使它不包括头文件的动态H 评论会员:
时间:您好,
我读第二TME仍然看起来很有趣,不错的主意,你得到了我的5
坚持做下去。
,阿南德。评论会员:
时间:首页所有伟大的文章!
我设法调用默认构造函数,但参数构建函数? 评论会员:
时间:以同样的方式,您如何出口非参数的构造函数,只是出口的另一个构造函数与一些不同的名称说CCtorOvl​​(你可以给任何名称),然后得到的地址,指定名称您在DEF文件,并​​调用它,不要忘记创建,correspondng函数指针。
,阿南德。评论会员:
时间:您好,我想要做的正是在这篇文章中描述,但我没有带了DLL的头文件。我该怎么办呢?关于托比亚斯
要么你住,或者你是随之而来的的评论会员:
时间:本文介绍:/cpp/cpp/cpp_mfc/tutorials/article.php/c9855__1
编程快乐! 评论会员:
时间:好文章的人。我喜欢的方式构造称为UR文章。但是,如果我有一个类似的问题要解决,我会去CALSS工厂而棘手的黑客技术用于ü比。但是一个很好的一个。
机体零件托马斯
- 5:02星期日三月二十六日,2006年修改评论会员:
时间:好主意Anup....大家都看到拆卸......但..优秀..一个小bug..它给我的内存泄漏VC++6.0SP5的....像往常一样调用析构函数和调用free(pCalc)会解决这个问题阿南德。阿尔钦Hakobyan评论会员:
时间:!阿南德在我写的,看到代码项目..我想,"哦,我忘了调用析构函数和自由的MEM......",但我没有更新代码项目...感谢你..关于AnupShubha巴勃罗Aliskevicius评论会员:
时间:和意见也imgsrc=/upimg/_21_09_22_3.gif我5的文章和评论。#定义__ARMEN_H__罗伯特雪兔评论会员:
时间:因为我懒惰,每当我有类似的需要我做以下几点:1。链接"延迟加载"DLL。这样,我可以编写代码,如果我是使用隐式链接。2。在第一次调用任何DLL中的函数(或变量,类......)之前,调用LoadLibrary(和处理问题,如果它没有加载)。3。最后一次使用后的DLL,调用FreeLibrary。当然,我得到的一个litlle类,它处理与RAII调用LoadLibrary/FreeLibrary则...这样,您就可以得到两全其美:使用早期绑定的易用性,并能够卸载DLL,当你不需要它只是我的两位...imgsrc=/upimg/_21_09_22_3.gifPablo_A alnikolov评论会员:
时间:构造函数调用的一部分,是不是很漂亮恕我直言。我做过类似的东西,然后我用DLL中的类的静态构造函数,如:用extern"C"CCalc*CALC_APIgetNewObject()在CPPCCalc*CALC_APIgetNewObject(){ 新CCalc();}缺点是,你只能调用指定的构造函数,但通常这是没有问题,手头的任务通常是定义。另一个与此扭曲是CCalc(即使用它作为一个接口),你可以继承的功能,并在不同的DLL的不同的实现。有用的一个插件架构(需要接口的开销低)黑色荷鲁斯评论会员:
时间:破解,我想给5,但每当我用我用不同的方法,用LoadLibrary加载的DLLclases:1。我宣布为"虚拟"的所有类的成员函数。我会从我的类的一个实例创建的DLL函数的出口。您将需要每类函数的构造。当您使用的类,你不需要进行任何黑客。当你调用"共创"的功能,它会返回一个类的指针,其中包含完全初始化的虚拟表。然后调用的功能,你会叫他们如果在一个DLL类。这里是一些例子:在您的DLL://ClassA.h类CClassA{市民:CClassA(){};{BR}虚拟〜CClassA(){};{BR}虚拟无效VFoo()}CClassA*CreateA()//main.cpp的包括"ClassA.h"#包括"iostream的"使用命名空间无效CClassA:VFoo(){法院"\"CClassA:VFoo()\""}CClassA*CreateA(){返回新CClassA;}在您的DLL的DEF文件:图书馆ClassDll出口CreateA在程序中使用从DLL类:#包括"iostream的"使用命名空间包括"ClassA.h"的typedefCClassA*(*PCreate)()INT主(INTARGC,CHAR*ARGV[]){HMODULEHLIB=::LoadLibrary的("ClassDLL.dll");(HLIB==NULL){法院LT,LT;"LoadLibrary的失败" 返回1;}PCreatepCreateFn=(PCreate)::GetProcAddress函数(HLIB,"CreateA");如果(!pCreateFn){法院LT,LT"GetProcAddress函数(HLIB,\"CreateA\")失败"返回1;}CClassA*PA=pCreateFn();PA-VFoo()返回0;} 与文明的问题是愚蠢的。我不是说应该有一个愚蠢的死刑,但为什么我们不只是安全标签的一切,让问题解决本身?DaviziN评论会员:
时间:和COM工作如何...。!:- DaviziN评论会员:
时间:对不起,我愚蠢的问题,但我得到一个exe文件创建错误,。"无法解析的外部CTest::〜CTest()...."{BR}?任何想法,我刚才定义它作为你的虚拟,但我呼吁:删除PTEST;从主程序释放内存。什么我做错了什么?在此先感谢,我与DLL的新(我也与生成器彗星的工作,这是一种痛苦imgsrc=/upimg/_21_09_22_3.gif) alnikolov评论会员:
时间:我避免的问题定义一个虚函数,称为"破坏()"是这样的:CTest*CTest:破坏(无效){删除;返回NULL;}是不是最好的解决办法,但如果它的工作原理,它可以对我罚款imgsrc=/upimg/_21_09_22_3.gif
&桌面&网页开发&移动开发&数据库&多媒体&编程语言&平台,框架和库&编程通用&图形/设计&开发周期&一般阅读&第三方产品&作者资源&其他
快速解答标签
价值作最多火炬之光2缺少libeay32.dll_百度知道SolidWorks2016提示 loadlibrary failed with error 1114 错误_百度知道

我要回帖

更多关于 quot什么意思 的文章

 

随机推荐